#! /usr/bin/env python
# coding=utf-8
#      bill.py    
#      
#      Copyright 2008 Dirk B. <dirkbo@googlemail.com>
#      
#      This program is free software; you can redistribute it and/or modify
#      it under the terms of the GNU General Public License as published by
#      the Free Software Foundation; either version 2 of the License, or
#      (at your option) any later version.
#      
#      This program is distributed in the hope that it will be useful,
#      but WITHOUT ANY WARRANTY; without even the implied warranty of
#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#      GNU General Public License for more details.
#      
#      You should have received a copy of the GNU General Public License
#      along with this program; if not, write to the Free Software
#      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#      MA 02110-1301, USA.


#Import Modules
try:
    import os, sys, math, random, pygame, time
    from pygame.locals import *

    if not pygame.font: print 'Warning, fonts disabled'
    #if not pygame.mixer: print 'Warning, sound disabled'

    from bill_sprites import *
    from ggfx import *
    #from online import *
    #from evpipe import *
    from billscreen import billscreen
    from gamepad import *
    from menu import *
    from highscores import *
    
    from optparse import OptionParser
    import re
    
except ImportError, err:
    print "Bullet Bill Battle - Error: ", err
    sys.exit(2)



#functions to create our resources

#  
#  name: load_sound
#  @param
#  @return
#def load_sound(name):
#   class NoneSound:
#      def play(self): pass
#   if not pygame.mixer or not pygame.mixer.get_init():
#      return NoneSound()
#   fullname = os.path.join('data', name)
#   try:
#      sound = pygame.mixer.Sound(fullname)
#   except pygame.error, message:
#      print 'Cannot load sound:', fullname
#      raise SystemExit, message
#   return sound

class Game():
    """The bullett bill Game class"""
    
    def __init__(self, bscreen):    
    
        #Enthält in der Map verwendete Grafiken
        self.mapgfx = Grafix(bscreen)
        self.mapxobjx = []
        self.mapvhobjx = []
        
        #Enthält nötige Angaben zum Onlineservice
        #self.service = Online()
        
        self.highscores = -1
        #self.sounds = Sounds()
        self.menu = Menu()
        self.menu.mainmenu()
        
        #bs übernimmt den von main geholten Bildschirm/Fenster
        self.bs = bscreen
        
        #Zeit in ms, die zur Berechnung des letzten Frames nötig war.
        self.lft = 16
        
        #Maximale Anzahl Computergesteuerter Bills
        self.fbillmax = 10
        
        #offset für trümmerberechnung:
        self.stckoffset = 1
        ## Die Kollisionen jedes n-ten stücks Schutt werden berechnet 
        self.do_schuttcoll = 3    
        
        # enthält die Kanonen des Levels
        self.spawnerlist = pygame.sprite.RenderPlain()
        
        #Die zeit, die ein Schuttstück fallen kann, bevor es sich auflöst
        self.schuttfall = 3000
        #Die Zeit in ms, die Schutt herumliegen bleibt, bevor er sich auflöst
        self.schuttzeit = 35000
        #Die zeit in ms, die Itemtrümmer liegen bleiben, bevor sie sich auflösen
        self.itemschuttzeit = 120000
        #Dei Zeit, um die die Lifetime neuer Objekte verändert wurde, wird an bestehende übergeben.
        self.ltc = 0
        
        # enthält zu zeichnende zerstörbare Objekte
        self.xblocksprites = pygame.sprite.RenderPlain()
        
        self.allowschutt = True
        
        # enthält zu zeichnende Fragezeichenblöcke 
        self.fblocksprites = pygame.sprite.RenderPlain()
        
        # enthält zu zeichnende Schuttstücke
        self.blockstsprites = pygame.sprite.RenderPlain()
        
        # Enthält zu zeichnende Hintergrundobjekte
        self.bodensprites = pygame.sprite.RenderPlain()
        
        # Enthält zu zeichnende Vordergrundobjekte
        self.vgrundsprites = pygame.sprite.RenderPlain()
        
        # Enthält die leeren Fragezeichenboxen
        self.fcreateblocksprites = pygame.sprite.RenderPlain()
        
        # Enthält die schwebenden Punktemeldungen
        self.scores = pygame.sprite.RenderPlain()
        
        #enthält die zu zeichnenden Items
        self.itemslist = []
        
        #Wenn true, werden keine neuen XBlöcke erstellt und Schutt bleibt liegen.
        self.persistent = True
        
        #Enthält die Aufzeichnung der eigenen für das Spiel relevanten Events
        #self.evpipe = GPipe()
        #Enthält die Aufzeichnung der fremden für das Spiel relevanten Events
        #self.inpipe = GPipe()
        #Gibt an, wie mit Eventpipes umgegangen werden soll (0=nicht verwenden, 1=aufzeichnen 2=abspielen 3=online)
        self.replay = 0
        #Bewegungsrichtung im Replay
        self.rep_move = 0
        
        #Enthält immer im Spiel wiederkehrende grafiken
        self.gfx = Grafix(bscreen)
        self.get_background()
        self.loadscreen("Spielgrafiken")
        ## Grafiken laden:
        # 0:
        self.gfx.load('bill.bmp')
        self.gfx.load('bill_blinz.bmp')
        self.gfx.load('bill_faust.bmp')
        self.gfx.load('bill_invincible1.bmp')
        self.gfx.load('bill_invincible2.bmp')
        self.gfx.load('bill_invincible3.bmp')
        self.gfx.load('bill_invincible4.bmp')
        self.gfx.load('bill_grun.bmp')
        # 8:
        self.gfx.load('rauch0.bmp')
        self.gfx.load('rauch1.bmp')
        self.gfx.load('rauch2.bmp')
        self.gfx.load('rauch3.bmp')
        self.gfx.load('rauch4.bmp')
        self.gfx.load('rauch5.bmp')
        # 14:
        self.gfx.load('item_turbo_0.bmp')
        self.gfx.load('item_turbo_1.bmp')
        self.gfx.load('item_turbo_2.bmp')
        self.gfx.load('item_turbo_3.bmp')
        self.gfx.load('item_turbo_4.bmp')
        self.gfx.load('item_turbo_5.bmp')
        self.gfx.load('item_turbo_6.bmp')
        self.gfx.load('item_turbo_7.bmp')
        self.gfx.load('item_turbo_8.bmp')
        ## Bilder von Item 2: Mine laden
        self.gfx.load('mine1.bmp')
        self.gfx.load('mine2.bmp')
        ## Symbol von Item 3: Grüner Bill laden
        self.gfx.load('item_grun.bmp')
        ## Symbol von Item 4: Unverwundbarkeit laden
        self.gfx.load('item_gold.bmp')
        # 27:
        self.gfx.load('frag1.bmp')
        self.gfx.load('frag2.bmp')
        self.gfx.load('frag3.bmp')
        self.gfx.load('frag4.bmp')
        self.gfx.load('frag5.bmp')
        self.gfx.load('frag6.bmp')
        # 33:
        self.gfx.load('fragleer0.bmp')
        self.gfx.load('fragleer1.bmp')
        # 35:
        self.gfx.load('item_scbox.bmp')
        # 36:
        self.gfx.load('billspawner.bmp')
        # 37:
        self.gfx.load('billstuck1.bmp')
        self.gfx.load('billstuck2.bmp')
        self.gfx.load('billstuck3.bmp')
        self.gfx.load('billstuck4.bmp')
        ##Verbrauchte Mine
        self.gfx.load('minedark.bmp')
        ##Verbrauchter Turbo
        self.gfx.load('turbodark.bmp')
        # 43:
        self.gfx.load('timebox.bmp')
        # 44
        self.gfx.load('livebox.bmp')
        # 45
        
        #Itemrechteck holen und positionieren
        self.itembox = self.gfx.get(35)
        self.itemboxrect = self.itembox.get_rect()
        self.itemboxrect.top = 0
        self.itemboxrect.left = int((self.bs.xres / 2.0) - (self.itemboxrect.width / 2.0))
        
        #Zeitbox holen
        self.timebox = self.gfx.get(43)
        self.timebox_rect = self.itembox.get_rect()
        self.timebox_rect.top = int(self.bs.yres * 0.88)
        self.timebox_rect.left = int(self.bs.xres / 65)
        
        #livebox holen
        self.livebox = self.gfx.get(44)
        self.livebox_rect = self.livebox.get_rect()
        self.livebox_rect.top = 0
        self.livebox_rect.left = int(self.bs.xres / 50)
        
        #enthält nicht vom Spieler gesteuerte Bills
        self.andrebills = pygame.sprite.RenderPlain()
        #Als Liste, für bessere Iteration
        #self.fremdbills = []
        
        # Bei der Replay-Aufzeichung, jede Sekunde die Weltverschiebung speichern
        self.wupd = 1000
        
        #Enthält Rauchwolken und explosionen
        self.smokesprites = pygame.sprite.RenderPlain()
        
        # Zeit, bis bill zur kanone verschoben wird
        self.timetolaunch = -1000
        
        #Zeit im aktuellen Spiel
        self.time = 0
        self.timemin = 0
        self.timesec = 0
        self.timemsc = 0
        #Zeitmodus im aktuellen Spiel, up(True) oder down(False)
        self.timemode = True
        
        #True, wenn Spieler ein Item benutzen möchte
        self.useItem = False
        
        #enthält objekte, die Schutt auffangen nzw. bills explodieren lassen
        self.KollHard = [] 
        
        #enthält ein angeschlossenes und konfiguriertes Gamepad
        self.gamepad = Gamepad(-1)
        
        ##Abwurfbereites Item
        self.item = 0
        
        ##Enthält den aktuellen Punktestand
        self.score = 0
        ##Enthält den letzten punktestand
        self.oldscore = -1
        ##Enthält die anzahl der Frames, in denen die Anzahl Leben noch sichtbar ist
        self.drawups = 0
        
        #enthält die Grenzen des Levels
        self.levelsize = Rect(0,0,self.bs.xres, self.bs.yres)
        self.left_wall = Rect(0,0, 10, 10)
        self.right_wall = Rect(0,0, 10, 10)
        self.top_wall = Rect(0,0, 10, 10)
        self.bottom_wall = Rect(0,0, 10, 10)
        
        #der vom Spieler kontrollierte Kugelwilli
        self.bill = Bill(self.bs, 200,200,0,0,1,self.gfx)
        self.bill.typ = 0
        
        # Die zu Beginn verfügbaren Leben
        self.ups = 3
        #die zuletzt gehabten ups
        self.oldups = 0
        
        # der Spielttyp
        self.mode = 1
        ## 1 = Punktejagd
        ## 2 = Race
        ## 3 = Battle
        ## 4 = Hioghscores
        
        ## die im Spiel befindlichen Spieler
        self.players = 1
        
        ## das zu ladende/gerade gespielte Level
        self.map = "level1.lev"
        ##das geladene Level
        self.loadedmap = ""
        
        
        self.fadecolor = (0,0,0)
        self.state = "prep_splash"
        self.t = 0
        self.max = 0
        self.nextstate = ""
        self.reset()
        try:
            self.player_name = os.environ["USER"]
        except KeyError:
            try:
                self.player_name = os.environ["USERNAME"]
            except KeyError:
                self.player_name = "Player"
                
    def start(self):
        self.state = "ingame"
        
    def loadscreen(self, message="", now=-1, max=-1):
        screen = pygame.display.get_surface()
        self.background.fill((0,0,0))
        text1 = self.gfx.menufont_h1.render("Loading...", 1, (255, 255, 255))
        textpos1 = text1.get_rect(centerx=self.bs.xres/2, centery=self.bs.yres/3)
        self.background.blit(text1, textpos1)
        text2 = self.gfx.menufont_h2.render(message, 1, (155, 155, 155))
        textpos2 = text1.get_rect(centerx=self.bs.xres/2, centery=self.bs.yres/3 + textpos1.height )
        self.background.blit(text2, textpos2)
        screen.blit(self.background, (0, 0))
        pygame.display.flip()

    def menu_down(self):
        self.menu.movedown()
        
    def menu_up(self):
        self.menu.moveup()

    def menu_select(self):
        if self.menu.selected != None:
            newstate = self.menu.items[self.menu.selected].changestate
            if newstate.endswith('.lev') == True:
                self.map = newstate
                if self.nextstate == 4:
                    self.state = "prep_highscores"
                    self.highscores = HighScores()
                    self.highscores.set(self.map, self.mode)
                    self.highscores.load()
                    self.nextstate = ""
                else:
                    self.state = "reset"
                
            if newstate == "mainmenu":
                self.highscores = -1
                self.menu.mainmenu()
            
            #Replays sind derzeit deaktiviert.  
            elif newstate == "replay":
            #   ghost = self.menu.get_option()
            #   ghost = "YWrHtMwPtH"
            #   print "replay "+ ghost+ ".dat"
            #   self.replay = 2
            #   self.inpipe.load(ghost, self.service)
            #   self.map = self.inpipe.level
            #   self.mode = self.inpipe.mode
            #   self.load(self.map+".lev", ghost)
            #   if self.service.useservice:
            #      if self.inpipe.maphash != self.get_maphash():
            #          self.service.report_replay(str(ghost), "INV_HASH")
            #          self.prep_highscores()
            #          return
                self.state = "reset"
                
            elif newstate == "credits":
                self.menu.creditsmenu()
                
            elif newstate == "scores":
                self.state = "prep_highscores"
                #self.menu.highscoresmenu(self.highscores)
                
            elif newstate == "newgameplayers":
                self.menu.newgameplayers()
                
            elif newstate == "newgamesingle":
                self.menu.newgamesingle()
                self.players = 1
                
            elif newstate == "newgamemulti":
                self.menu.newgamemulti()
                self.players = 2
                
            elif newstate == "returntogame":
                self.max = 30
                self.nextstate = "ingame"
                
            elif newstate == "options":
                self.menu.options()
                
            elif newstate == "conf_joys":
                self.state = "conf_joys"
            
            #Online Service ist derzeit deaktiviert
            #elif newstate == "conf_service":
            #   self.menu.oservicemenu(self.service.uname, self.service.server)
                
            elif newstate == "conf_username":
                self.state = "conf_username"    
            
            elif newstate == "conf_pw":
                self.state = "conf_pw"  
            #Online Service ist derzeit deaktiviert 
            #elif newstate == "save_service":
            #   if self.testservice():
            #      self.service.saveuser()
            #   self.state = "mainmenu" 
            #   self.highscores = -1
            #   self.menu.mainmenu()    
                
            elif newstate == "newgamesinglescore":
                self.mode = 1
                self.menu.levelsmenu()
                self.state = "mainmenu"
            
            elif newstate == "newgamesinglerace":
                self.mode = 2
                self.menu.levelsmenu()
                self.state = "mainmenu"
                
            elif newstate == "quit":
                self.state = "quit"
                
    def testservice(self):
        #self.loadscreen("Teste Online Service konfiguration")
        #v = self.service.test()
        #self.get_background()
        #Online Service ist deaktiviert -> Immer False zurückgeben
        return False
                
    def ingamemenu(self):
        self.state = "mainmenu"
        self.menu.ingamemenu()
        
    def get_current_menu(self):
        return self.menu.items
        
    def reset(self):
        self.score = 0
        self.bill.id = -1
        if self.replay == 2:
            self.bill.keepinscreen = False
        else:
            self.bill.keepinscreen = True
        self.ups = 3
        if self.mode == 1:
            self.time = 3 * 60000
            if self.replay == 2:
                self.time = 3 * 60000 + 1000
            self.timemode = False
        elif self.mode == 2:
            self.time = 0
            if self.replay == 2:
                self.time = -2000
            self.timemode = True
        
        
    def takelife(self):
        self.oldups = self.ups
        self.bill.invincible = -1000
        if self.replay != 2:
            if self.ups > 1:
                self.ups -= 1
                self.prepshootbill()
                self.bill.kill = False
                ##Anzahl Leben anzeigen
                self.drawups = 5000 
            else:
                self.state = "gameover"
        else:
            self.ups -= 1
            self.prepshootbill()
            
    def shootbill(self, typ):
        ## erstellt einen neuen Bill mit speed = 100 und setzt ihn an die Position einer beliebigen Kanone    
        ## bill abschießen
        if typ == 1:
            #if self.replay != 2:
            nb = Bill(self.bs, sr.left, sr.top, 1, sr.width, sr.height, self.gfx, self.lft)
            self.andrebills.add(nb)
            #self.fremdbills.append(nb)          
                
        if typ == 0:
            #bill zurücksetzen    
            self.bill.shoot = 3200
            
            
    def checkforshoot(self):
        # Zeit, bis bill zur kanone verschoben wird
        if self.timetolaunch != -1000:
            self.timetolaunch -= self.lft
            if self.timetolaunch <= 0:
                self.timetolaunch = -1000
                self.takelife() 
                                    
    def prepshootbill(self):
        ## verschiebt Bill an die position einer Kanone
        ## Zufällig einen Spawner auswählen
        ##  wdth => minimum Abschuss Radius
        ##  height => wird maximal zu minimalem radius addiert.
        self.bill.allowmove = False
        self.bill.visible = False
        sr = Rect (100, 100, 0, 0)
        for aspawn in self.spawnerlist:
            sr.top = aspawn.rect.top
            sr.left = aspawn.rect.left
            sr.width = 0
            sr.height = 0
        ## macht Bill unsichtbar
        ## welt verschieben, so dass sr in der Bildmitte liegt
        ## also: Sr.left richtung 512 um 1 erhöhen/verkleinern
        ## richtet einen zähler ein, der den Abschuss auslöst
        centerx = int(self.bs.xres/2)
        centery = int(self.bs.yres/2)
        xof = sr.left - centerx
        yof = sr.top - centery
        ##     im Gegenzug alles in der Welt um 1 verkleinern/erhöhen
        #if self.replay != 2 and self.bill.keepinscreen:
        self.moveworld(xof, yof)
        sr.left = sr.left - xof
        sr.top = sr.top - yof
        #elif self.replay == 2 and self.inpipe.inited == False:
        #   print "Level: ",self.levelsize
        #   #self.moveworld(xof, yof)
        #   #self.inpipe.movewithworld(xof,yof)
        #   print "Inpipe: ", self.levelsize.left - xof, self.levelsize.top - yof, self.levelsize.width, self.levelsize.height
        #   self.inpipe.inited = True
        #elif self.replay == 2 and self.bill.keepinscreen == True:
        #   self.moveworld(xof, yof)
        #   self.inpipe.movewithworld(xof,yof)
        
        #if self.replay == 1:
        #   g = GEvent()
        #   g.set_gzero(self.zerox,self.zeroy, self.time)
        #   self.evpipe.add(g)
        self.bill.rect.top = sr.top
        self.bill.rect.left = sr.left
        #print "Neues Bill x: ", self.bill.
        self.bill.reset()
        #if self.replay == 1:
        #   g = GEvent()
        #   #g.set_gzero(self.zerox,self.zeroy, self.time)
        #   g.set_normal(self.zerox, self.zeroy)
        #   g.set_bill(-1, self.bill.rect.left, self.bill.rect.top , 0, 0, 0, self.time)
        #   self.evpipe.add(g)
        #if self.replay !=2:
        self.shootbill(0)
            
    # verschiebt die gesamte Welt um xof, yof
    def moveworld(self, xof, yof):
        for xblock in self.xblocksprites:
            xblock.rect.left -= xof
            xblock.rect.top -= yof
        for fblock in self.fblocksprites:
            fblock.rect.left -= xof
            fblock.rect.top -= yof
        for boden in self.bodensprites:
            boden.rect.left -= xof
            boden.rect.top -= yof
        for vg in self.vgrundsprites:
            vg.rect.left -= xof
            vg.rect.top -= yof
        for aspawn in self.spawnerlist:
            aspawn.rect.left -= xof
            aspawn.rect.top -= yof
        for blockst in self.blockstsprites:
            blockst.rect.left -= xof
            blockst.rect.top -= yof
        for fcblock in self.fcreateblocksprites:
            fcblock.rect.left -= xof
            fcblock.rect.top -= yof
        for hkoll in self.KollHard:
            hkoll.rect.left -= xof
            hkoll.rect.top -= yof
        self.movelevel(xof,yof)
        for item in self.itemslist:
            if item.deployed == True:
                item.rect.top -= yof
                item.rect.left -= xof   
        for smoke in self.smokesprites:
            smoke.rect.left -= xof
            smoke.rect.top -= yof
        
        for abill in self.andrebills:
            abill.rect.left -= xof
            abill.rect.top -= yof
        #Nullpunkt der Map verschiebt sich mit der Welt, entgegen dem Spieler
        self.zerox -= xof
        self.zeroy -= yof
        #if self.replay == 2:
        #   #Normalisierte Geistdaten mit verschieben
        #   self.inpipe.movewithworld(xof, yof)
            
    def _getborders(self):
        ##vergleiche objekte in den eigenen arrays mit der levelgrenze und vergrößere sie,wenn nötig
        print "Bisherige Levelgröße: ", self.levelsize
        ##Levelgröße erst zurücksetzen, sonst könnten weiter im verlauf geladene Level nur größer werden
        self.levelsize = Rect(0,0,self.bs.xres,self.bs.yres)
        topmost = 0
        leftmost = 0
        rightmost = 0
        bottommost = 0
        
        for xblock in self.xblocksprites:
            if xblock.rect.top < topmost:
                topmost = xblock.rect.top
                
            if xblock.rect.left < leftmost:
                leftmost = xblock.rect.left
                
            if xblock.rect.right >rightmost:
                rightmost = xblock.rect.right
                
            if xblock.rect.bottom > bottommost:
                bottommost = xblock.rect.bottom
                
        for fblock in self.fblocksprites:
            if fblock.rect.top < topmost:
                topmost = fblock.rect.top
                
            if fblock.rect.left < leftmost:
                leftmost = fblock.rect.left
                
            if fblock.rect.right >rightmost:
                rightmost = fblock.rect.right
                
            if fblock.rect.bottom > bottommost:
                bottommost = fblock.rect.bottom
                
        for boden in self.bodensprites:
            if boden.rect.top < topmost:
                topmost = boden.rect.top
                
            if boden.rect.left < leftmost:
                leftmost = boden.rect.left
                
            if boden.rect.right >rightmost:
                rightmost = boden.rect.right
                
            if boden.rect.bottom > bottommost:
                bottommost = boden.rect.bottom
                
        for vg in self.vgrundsprites:
            if vg.rect.top < topmost:
                topmost = vg.rect.top
                
            if vg.rect.left < leftmost:
                leftmost = vg.rect.left
                
            if vg.rect.right >rightmost:
                rightmost = vg.rect.right
                
            if vg.rect.bottom > bottommost:
                bottommost = vg.rect.bottom
        
        for aspawn in self.spawnerlist:
            if aspawn.rect.top < topmost:
                topmost = aspawn.rect.top
                
            if aspawn.rect.left < leftmost:
                leftmost = aspawn.rect.left
                
            if aspawn.rect.right >rightmost:
                rightmost = aspawn.rect.right
                
            if aspawn.rect.bottom > bottommost:
                bottommost = aspawn.rect.bottom
            
        ##Überprüfung für Kollisionsobjekte nicht nötig, berits als boden/hgrund bzw. vgrund erledigt
        self.levelsize = Rect(leftmost, topmost,(leftmost*(-1)+rightmost),(topmost*(-1)+bottommost) )
        print "Neue Levelgröße: ", self.levelsize
        if leftmost < 0:
            for xblock in self.xblocksprites:
                xblock.rect.left += -1 * leftmost
                
            for fblock in self.fblocksprites:
                fblock.rect.left += -1 * leftmost
                
            for boden in self.bodensprites:
                boden.rect.left += -1 * leftmost
                
            for vg in self.vgrundsprites:
                vg.rect.left += -1 * leftmost
                
            for aspawn in self.spawnerlist:
                aspawn.rect.left += -1 * leftmost
                
            for kh in self.KollHard:
                kh.rect.left += -1 * leftmost
            #Levelgröße anpassen
            self.levelsize.left += -1 * leftmost
                
        if topmost < 0:
            for xblock in self.xblocksprites:
                xblock.rect.top += -1 * topmost
                
            for fblock in self.fblocksprites:
                fblock.rect.top += -1 * topmost
                
            for boden in self.bodensprites:
                boden.rect.top += -1 * topmost
                
            for vg in self.vgrundsprites:
                vg.rect.top += -1 * topmost
                
            for aspawn in self.spawnerlist:
                aspawn.rect.top += -1 * topmost
                
            for kh in self.KollHard:
                kh.rect.top += -1 * topmost
            #Levelgröße anpassen
            self.levelsize.top += -1 * topmost
            #Verschiebung auf 0 setzen
        print "Level nach Verschieben: ", self.levelsize
            
    def savemapXML(self):
         ###Pseudo-Write XML-version of level
        from xml.sax.saxutils import XMLGenerator
        from xml.sax.xmlreader import AttributesNSImpl
        
        """
        Set up a logger object, which takes SAX events and outputs
        an XML log file
        """
        filename = os.path.join("data/", self.get_maphash()+".xlv")
        fp = open(filename, "w")
        
        logger = XMLGenerator(fp, 'utf-8')
        logger.startDocument()
        attrs = AttributesNSImpl({}, {})
        logger.startElementNS((None, u'map'), u'map', attrs)
      
        ### level Objekte schreiben
        for aspawn in self.spawnerlist:
            aspawn.writeXML(logger)
        for boden in self.bodensprites:
            boden.writeXML(logger, self.mapgfx)

        """
        Clean up the logger object
        """
        logger.endElementNS((None, u'map'), u'map')
        logger.endDocument()
        fp.close()

        ###
            
    def _unload(self):
        #self.savemapXML()
        for xblock in self.xblocksprites:
            self.xblocksprites.remove(xblock)
        for fblock in self.fblocksprites:
            self.fblocksprites.remove(fblock)
        for boden in self.bodensprites:
            self.bodensprites.remove(boden)
        self.vgrundsprites.empty()        
        for aspawn in self.spawnerlist:
            self.spawnerlist.remove(aspawn)
        for blockst in self.blockstsprites:
            self.blockstsprites.remove(blockst)
        for fcblock in self.fcreateblocksprites:
            self.fcreateblocksprites.remove(fcblock)
        for score in self.scores:
            self.scores.remove(score)
        for smoke in self.smokesprites:
            self.smokesprites.remove(smoke)
        for abill in self.andrebills:
                self.andrebills.remove(abill)
        #self.fremdbills = []
        self.levelsize = Rect(0,0,self.bs.xres,self.bs.yres)
        self.KollHard = []
        self.itemslist = []
        self.mapgfx.unload()
        self.mapxobjx = []
        self.mapvhobjx = []
        #Enthät den globalen Nullpunkt
        self.zerox = 0
        self.zeroy = 0
        
    def _resizemap(self):
        for xblock in self.xblocksprites:
            xblock.rect.left = int(round(xblock.rect.left * self.gfx.fx))
            xblock.rect.top  = int(round(xblock.rect.top * self.gfx.fy))
            #xblock.rect.left = xblock.rect.left * self.gfx.fx
            #xblock.rect.top  = xblock.rect.top * self.gfx.fy
        for fblock in self.fblocksprites:
            fblock.rect.left = int(round(fblock.rect.left * self.gfx.fx))
            fblock.rect.top  = int(round(fblock.rect.top * self.gfx.fy))
            #fblock.rect.left = fblock.rect.left * self.gfx.fx
            #fblock.rect.top  = fblock.rect.top * self.gfx.fy
        for boden in self.bodensprites:
            boden.rect.left = int(round(boden.rect.left * self.gfx.fx))
            boden.rect.top  = int(round(boden.rect.top * self.gfx.fy))
            #boden.rect.left = boden.rect.left * self.gfx.fx
            #boden.rect.top  =boden.rect.top * self.gfx.fy
        for vgrund in self.vgrundsprites:
            vgrund.rect.left = int(round(vgrund.rect.left * self.gfx.fx))
            vgrund.rect.top  = int(round(vgrund.rect.top * self.gfx.fy))    
            #vgrund.rect.left = vgrund.rect.left * self.gfx.fx
            #vgrund.rect.top  = vgrund.rect.top * self.gfx.fy   
        for aspawn in self.spawnerlist:
            aspawn.rect.left = int(round(aspawn.rect.left * self.gfx.fx))
            aspawn.rect.top  = int(round(aspawn.rect.top * self.gfx.fy))    
            #aspawn.rect.left = aspawn.rect.left * self.gfx.fx
            #aspawn.rect.top  = aspawn.rect.top * self.gfx.fy   
        self.levelsize.left = self.levelsize.left * self.gfx.fx
        self.levelsize.top = self.levelsize.top * self.gfx.fy
        self.levelsize.width = self.levelsize.width * self.gfx.fx
        self.levelsize.height = self.levelsize.height * self.gfx.fy
        for kh in self.KollHard:
            kh.rect.left = kh.rect.left * self.gfx.fx
            kh.rect.top  = kh.rect.top * self.gfx.fy
        self.left_wall = Rect(self.levelsize.left -100, self.levelsize.top, 100, self.levelsize.bottom) 
        self.right_wall = Rect(self.levelsize.right, self.levelsize.top, 100, self.levelsize.bottom)    
        self.top_wall = Rect(self.levelsize.left, self.levelsize.top -100, self.levelsize.right, 100)
        self.bottom_wall = Rect(self.levelsize.left, self.levelsize.bottom, self.levelsize.right, 100)  

    def _shrinkKol(self):
        prev = len(self.KollHard)
        neukol = []
        ## gleich hohe, angrenzende Kollisionsbereiche zusammenfassen
        for a in xrange(0, len(self.KollHard)):
            for b in xrange(a, len(self.KollHard)):
                #print "KollObjektr: ", self.KollHard[a], " - ",  self.KollHard[b]
                self.KollHard[a].widthmerge(self.KollHard[b])
        ## gleich breite, angrenzende Kollisionsbereiche zusammenfassen
        for a in xrange(0, len(self.KollHard)):
            for b in xrange(a, len(self.KollHard)):
                #print "KollObjektr: ", self.KollHard[a], " - ",  self.KollHard[b]
                self.KollHard[a].heightmerge(self.KollHard[b])
                
        ## alle Kolliosionsbereiche mit breite und höhe = 0 löschen
        count = 0
        for kol in self.KollHard:
            if kol.rect.height != 0 and kol.rect.width != 0:
                #print "Bleibt: ", kol.rect
                neukol.append(kol)
                count += 1
        post = len(neukol)
        self.KollHard = neukol
        print "Kollisionsblöcke vor Reduktion: ", prev
        print prev - count, " Kollisionsblöcke durch Zusammenführen entfernt!"
        print "  danach: ", post
        
    def movelevel(self, worldofx, worldofy):
        ##verschiebt das Levelrechteck, um die Bewegung des Spielers auszugleichen
        self.levelsize.top -= worldofy
        self.levelsize.left -= worldofx
        
        self.left_wall.top -= worldofy
        self.left_wall.left -= worldofx
        
        self.right_wall.top -= worldofy
        self.right_wall.left -= worldofx    
        
        self.top_wall.top -= worldofy
        self.top_wall.left -= worldofx
        
        self.bottom_wall.top -= worldofy
        self.bottom_wall.left -= worldofx
        
        
    def _loadpreset(self, name, px, py):
        fp = open(os.path.join("data/maps", name))
        pcontent = fp.read()
        ##Inhalt Zeile für Zeile in Array laden
        pline = []
        pline.append("")
        plcount = 0
        for i in xrange(0, len(pcontent)):
            if pcontent[i] == '\n':
                pline.append("")
                #print "Zeile komplett: ", pline[plcount]
                plcount += 1    
            else:
                pline[plcount] += pcontent[i]
        
        #presets auflösen      
        for i in xrange(0, len(pline)):
            if pline[i] == "preset":
                pfile = pline[i+1]
                pfx = int(pline[i+2])
                pfy = int(pline[i+3])
                print "Lade Preset ", pfile, "..."
                nl = self._loadpreset(pfile, pfx, pfy)
                for a in range(0, len(nl)):
                    pline.append(nl[a])
        
        ##Preset Objekte auflisten
        for i in xrange(0, len(pline)):
            if pline[i] == "hgrund":
                x = int(pline[i+1])
                pline[i+1] = px + x
                y = int(pline[i+2])
                pline[i+2] = py + y
                
            elif pline[i] == "ugrund":
                x = int(pline[i+1])
                pline[i+1] = px + x
                y = int(pline[i+2])
                pline[i+2] = py + y
                
            elif pline[i] == "xblock":
                x = int(pline[i+1])
                pline[i+1] = px + x
                y = int(pline[i+2])
                pline[i+2] = py + y
                #print "x in preset: ", x
                #print "y in preset: ", y
                #print "px in loader: ", px
                #print "py in loader: ", py
                #print " xbloxk: x:", pline[i+1]
                #print "         y:", pline[i+2]
            
            elif pline[i] == "fblock":
                x = int(pline[i+1])
                pline[i+1] = px + x
                y = int(pline[i+2])
                pline[i+2] = py + y
                
            elif pline[i] == "hardkoll":
                x = int(pline[i+1])
                pline[i+1] = px + x
                y = int(pline[i+2])
                pline[i+2] = py + y  
            elif pline[i] == "spawnbill":
                x = int(pline[i+1])
                pline[i+1] = px + x
                y = int(pline[i+2])
                pline[i+2] = py + y      
            #else:
                #print "Unerkannte Zeile:", pline[i]
                #x = int(pline[i+1])
                #pline[i+1] = px + x
                #y = int(pline[i+2])
                #pline[i+2] = py + y
                
        #objekte zurückgeben
        return pline    
        
        

    def load(self,name ="", replay=""):
        ## Wenn kerin name übergeben wurde, in self.map vorhandene Map laden
        if name == "":
            name =  self.map
        else:
            self.map = name
            
        if True == True:
            ## Bestehendes Level löschen
            self.loadscreen("Leere Map Daten")
            self._unload()
            print "Lade Map: ", name
            # Bill abbremsen
            self.bill.speed = 0
            self.bill.rotation = 0
            self.bill.worldx = 0
            self.bill.worldy = 0
            self.bill.rect.top = 300
            self.bill.rect.left = 500
            ##Datei öffnen
            self.loadscreen("Lese Map "+name)
            print "Öffne Map: ", os.path.join("data/maps", name)
            fp = open(os.path.join("data/maps", name))
            content = fp.read()
            ##Inhalt Zeile für Zeile in Array laden
            line = []
            line.append("")
            lcount = 0
            for i in xrange(0, len(content)):
                if content[i] == '\n':
                    line.append("")
                    #print "Zeile komplett: ", line[lcount]
                    lcount += 1 
                else:
                    line[lcount] += content[i]
        
            #presets auflösen
            for i in xrange(0, len(line)):
                if line[i] == "preset":
                    pfile = line[i+1]
                    pfx = int(line[i+2])
                    pfy = int(line[i+3])
                    print "Lade Preset ", pfile, "..."
                    self.loadscreen("Lese Preset "+pfile)
                    nl = self._loadpreset(pfile, pfx, pfy)
                    for a in xrange(0, len(nl)):
                        if nl[a] != "\n" and nl[a] != "":
                            #print "Aus Preset: ", nl[a]
                            line.append(nl[a])
        
            #Leere Listen bereitstellen
            self.mapvhobjx =  []
            self.mapxobjx = []
            self.mapgfx.unload()
            ##Spiel Objekte erstellen
            for i in xrange(0, len(line)):
                for xob in self.mapxobjx:
                    if i >= 1:
                        if line[i] == xob.name and line[i-1] != "define XObject":
                            #print xob.name, "XObjekt gefunden!" 
                            #x = round(self.gfx.fx * int(line[i+1]))
                            #y = round(self.gfx.fy * int(line[i+2]))
                            x = int(line[i+1])
                            y = int(line[i+2])
                            #TODO: prüfen, ob ok
                            #Zerstörbares Objekt erzeugen
                            xblck = XBlock(x, y, self.mapgfx, xob.firstnormal, xob.firstconstruct, xob.firstpiece, xob.lastpiece)
                            xblck.persistent = self.persistent
                            self.xblocksprites.add(xblck)
                            #print "Zerstörbares Element ",xob.name," hinzugefügt!"
                for vhob in self.mapvhobjx:
                    if i >= 1:
                        if line[i] == vhob.name and line[i-1] != "define VHObject":
                            #print vhob.name, "VHObject gefunden!" 
                            #x = round(self.gfx.fx * int(line[i+1]))
                            #y = round(self.gfx.fy * int(line[i+2]))
                            x = int(line[i+1])
                            y = int(line[i+2])
                            #print "t: ", line[i+3]
                            t = int(line[i+3])
                            k = int(line[i+4])
                            #TODO: prüfen, ob ok
                            #Hintergrundobjekt erzeugen
                            ## t soll festlegen, zu welchem Typ das Objekt kommt.
                            if t == 0:
                                boden = Boden(x, y, t, self.mapgfx, vhob.first, vhob.last)
                                self.bodensprites.add(boden)
                            elif t == 1:
                                boden = VGrund(x, y, t, self.mapgfx, vhob.first, vhob.last)
                                self.vgrundsprites.add(boden)
                            if k == 1:
                                w = boden.rect.width
                                h = boden.rect.height
                                self.KollHard.append(KollRect(Rect(x, y, w, h)))
                            else:
                                print "Kollisionsfrei!"
                            #self.xblocksprites.add(XBlock(x, y, self.mapgfx, xob.firstnormal, xob.firstconstruct, xob.firstpiece, xob.lastpiece))
                            #print "Zerstörbares Element ",xob.name," hinzugefügt!"
                #if line[i] == "hgrund":
                #   x = int(line[i+1])
                #   y = int(line[i+2])
                #   t = int(line[i+3])
                #   k = int(line[i+4])
                #   #TODO: prüfen, ob ok
                #   #Hintergrundobjekt erzeugen
                #   boden = Boden(x, y, t)
                #   self.bodensprites.add(boden)
                #   if k == 1:
                #      w = boden.rect.width
                #      h = boden.rect.height
                #      self.KollHard.append(KollRect(Rect(x, y, w, h)))
                #      #print " Harte Kollisions-Box erzeugt!"
                #   #print "Hintergrundelement geladen!"
                #elif line[i] == "xblock":
                #   x = int(line[i+1])
                #   y = int(line[i+2])
                #   #TODO: prüfen, ob ok
                #   #Hintergrundobjekt erzeugen
                #   self.xblocksprites.add(XBlock(x, y))
                #   #print "Zerstörbares Element geladen!"
                if line[i] == "persistent":
                    if line[i+1] == "True" and line[i+2] == "---":
                        self.persistent = True
                    elif line[i+1] == "False" and line[i+2] == "---":
                        self.persistent = False
                if line[i] == "define VHObject":
                    hg = VHObjx(line[i+1])
                    isnew = True
                    for vhg in self.mapvhobjx:
                        if vhg.name == hg.name:
                            isnew = False
                            print "Vordergrund/Hintergrund Element ", hg.name, " ist bereits definiert!"
                    if isnew:
                        print "Vordergrund/Hintergrund Element ", hg.name, " definiert!"
                        j = i+2
                        hg.first = len(self.mapgfx.gfx)
                        #print "Erstes Bild normaler Zustand = ", hg.first
                        while line[j] != "---":
                            if hg.originalwidth == -1 or hg.originalheight == -1:
                                hg.originalwidth, hg.originalheight = self.mapgfx.load(line[j])
                            else:
                                self.mapgfx.load(line[j])
                            hg.last = self.mapgfx.get_len() -1
                            #print "Bild hinzugefügt: ", line[j]
                            j += 1
                        #print "Letztes Bild = ", hg.last
                        self.mapvhobjx.append(hg)
                elif line[i] == "define XObject":
                    xb = XObjx(line[i+1])
                    #Prüfen, ob Element bereits definiert:
                    isnew = True
                    for xob in self.mapxobjx:
                        if xb.name == xob.name:
                            isnew = False
                            #print "Zerstörbares Element ", xb.name, " ist bereits definiert!"
                    if isnew:
                        #print "Zerstörbares Element ", xb.name, " definiert!"
                        j = i+2
                        xb.firstnormal = len(self.mapgfx.gfx)
                        #print "Erstes Bild normaler Zustand = ", xb.firstnormal
                        while line[j] != "+++":
                            #if line[j] != "+++":
                            self.mapgfx.load(line[j])
                            xb.lastnormal = self.mapgfx.get_len() -1
                            #print "Bild für normalen Zustand hinzugefügt: ", line[j]
                            j += 1
                        #print "Letztes Bild normaler Zustand = ", xb.lastnormal
                        j+=1
                        xb.firstconstruct = self.mapgfx.get_len()
                        #print "Erstes Bild Konstruktions Zustand = ", xb.firstconstruct
                        while line[j] != "+++":
                            #if line[j] != "+++":
                            self.mapgfx.load(line[j])
                            xb.lastconstruct = self.mapgfx.get_len() -1
                            #print "Bild für Konstruktions Zustand hinzugefügt: ", line[j]
                            j += 1
                        #print "Letztes Bild Konstruktions Zustand = ", xb.lastconstruct
                        j+=1
                        xb.firstpiece = self.mapgfx.get_len()
                        #print "Erstes Bild Stückelchen Zustand = ", xb.firstpiece
                        while line[j] != "---":
                            #if line[j] != "---" and line[j] != "+++":
                            self.mapgfx.load(line[j])
                            xb.lastpiece = self.mapgfx.get_len() -1
                            #print "Bild für Stücke hinzugefügt: ", line[j]
                            j += 1
                        #print "Letztes Bild Stückelchen Zustand = ", xb.lastpiece
                        self.mapxobjx.append(xb)
                elif line[i] == "fblock":
                    #x = int(self.gfx.fx *int(line[i+1]))
                    #y = int(self.gfx.fy *int(line[i+2]))
                    x = int(line[i+1])
                    y = int(line[i+2])
                    #TODO: prüfen, ob ok
                    #Hintergrundobjekt erzeugen
                    self.fblocksprites.add(Fblock(x, y, self.gfx))
                    #print "Fragezeichen-Box geladen!"
                elif line[i] == "hardkoll":
                    x = int(line[i+1])
                    y = int(line[i+2])
                    w = int(line[i+3])
                    h = int(line[i+4])
                    #TODO: prüfen, ob ok
                    #Hintergrundobjekt erzeugen
                    self.KollHard.append(KollRect(Rect(x, y, w, h)))
                elif line[i] == "spawnbill":
                    #x = int(self.gfx.fx *int(line[i+1]))
                    #y = int(self.gfx.fy *int(line[i+2]))
                    x = int(line[i+1])
                    y = int(line[i+2])
                    t = int(line[i+3])
                    rmin = int(line[i+4])
                    rmax = int(line[i+5])
                    #TODO: prüfen, ob ok
                    #Hintergrundobjekt erzeugen
                    self.spawnerlist.add(Billspawner(x, y, self.gfx, t, rmin, rmax))
                    #print "Bill-Spawner geladen!"
            
            ## levelgröße berechnen
            self.loadscreen("Berechne Levelgröße")
            self._getborders()
            ## Map an Auflösung anpassen
            self.loadscreen("Skaliere Grafiken ")
            self._resizemap()
            ## Kollisionsrechtecke reduzieren
            self.loadscreen("Reduziere Kollisionsobjekte ")
            self._shrinkKol()   
            ## Kollisionsrechtecke zu int umwandeln
            for kh in self.KollHard:
                kh.rect.left = int(round(kh.rect.left))
                kh.rect.top  = int(round(kh.rect.top))
        else:
            ## levelgröße neue berechnen und auf NUllpunkt verschieben
            self.loadscreen("Berechne Levelgröße")
            self._getborders()
            #Map leeren
            for blockst in self.blockstsprites:
                self.blockstsprites.remove(blockst)
            for score in self.scores:
                self.scores.remove(score)
            for smoke in self.smokesprites:
                self.smokesprites.remove(smoke)
            for abill in self.andrebills:
                self.andrebills.remove(abill)
            #self.fremdbills = []
            self.itemslist = []
            #Enthät den globalen Nullpunkt
            self.zerox = 0
            self.zeroy = 0
            
        ##Anzahl Leben anzeigen
        self.drawups = 5000 
        ## Normalisierung des Replays, xf, yf setzen
        #if self.replay == 1:
        #   self.evpipe.set_xyf(self.gfx.fx, self.gfx.fy)
        ## Geist laden
        #if self.replay == 2 and replay != "":
        #   self.loadscreen("Lade Replay ")
        #   self.inpipe.set_map(self.map)
        #   self.inpipe.set_xyf(self.gfx.fx, self.gfx.fy)
        #   self.inpipe.rang = 1
        #   self.inpipe.mode = self.mode
        #   self.inpipe.load(replay)
        #   self.loadscreen("Replay an eigene Auflösung anpassen")
        #   self.inpipe.scale(self.bs.xres, self.bs.yres)
        self.get_background()
        self.loadedmap = self.map
        
        


    #Rauch erstellen?
    def create_smokeEigen(self):
        if self.bill.smokecount == 0 and self.bill.speed > 0.5:
            smoke = Smoke(self.bill.rect, 75, self.gfx)
            self.smokesprites.add(smoke)
            
    def get_maphash(self):
        import hashlib
        
        m = hashlib.md5()
        stri = self.map

        ##Map kollHard Objekte neu einlesen
        ##Datei öffnen
        #self.loadscreen("Lese Map "+name)
        fp = open(os.path.join("data/maps", self.map))
        content = fp.read()
        ##Inhalt Zeile für Zeile in Array laden
        line = []
        line.append("")
        lcount = 0
        for i in xrange(0, len(content)):
            if content[i] == '\n':
                line.append("")
                #print "Zeile komplett: ", line[lcount]
                lcount += 1 
            else:
                line[lcount] += content[i]
                
        #presets auflösen
        for i in xrange(0, len(line)):
            if line[i] == "preset":
                pfile = line[i+1]
                pfx = int(line[i+2])
                pfy = int(line[i+3])
                #print "Lade Preset ", pfile, "..."
                #self.loadscreen("Lese Preset "+pfile)
                nl = self._loadpreset(pfile, pfx, pfy)
                for a in range(0, len(nl)):
                    if nl[a] != "\n" and nl[a] != "":
                        #print "Aus Preset: ", nl[a]
                        line.append(nl[a])    
                
        #Kollisionen und Spawner auflösen
        for i in xrange(0, len(line)):
            for vhob in self.mapvhobjx:
                if i >= 1:
                    if line[i] == vhob.name and line[i-1] != "define VHObject":
                        #print vhob.name, "VHObject gefunden!" 
                        #x = round(self.gfx.fx * int(line[i+1]))
                        #y = round(self.gfx.fy * int(line[i+2]))
                        x = int(line[i+1])
                        y = int(line[i+2])
                        #print "t: ", line[i+3]
                        t = int(line[i+3])
                        k = int(line[i+4])
                        #TODO: prüfen, ob ok
                        if k == 1:
                            w = vhob.originalwidth
                            h = vhob.originalheight
                            stri += str(x) + str(y) + str(t) + str(w) + str(h)
                        #self.xblocksprites.add(XBlock(x, y, self.mapgfx, xob.firstnormal, xob.firstconstruct, xob.firstpiece, xob.lastpiece))
                        #print "Zerstörbares Element ",xob.name," hinzugefügt!"
            if line[i] == "hardkoll":
                x = int(line[i+1])
                y = int(line[i+2])
                w = int(line[i+3])
                h = int(line[i+4])
                #TODO: prüfen, ob ok
                #Hintergrundobjekt erzeugen
                stri += str(x) + str(y) + str(w) + str(h)
            elif line[i] == "spawnbill":
                #x = int(self.gfx.fx *int(line[i+1]))
                #y = int(self.gfx.fy *int(line[i+2]))
                x = int(line[i+1])
                y = int(line[i+2])
                t = int(line[i+3])
                rmin = int(line[i+4])
                rmax = int(line[i+5])
                #TODO: prüfen, ob ok
                #Hintergrundobjekt erzeugen
                stri += str(x) + str(y) + str(t) + str(rmin)+ str(rmax)
                #print "Bill-Spawner geladen!"
        
        #print "Hashbasis: ", stri
        m.update(stri)
        hash = m.hexdigest()
        print "Hash  : ", hash   
        return hash
            
    def collide_Andrebills(self):
        # Für jeden Fremdbill
            
        for abill in self.andrebills:
            #rauch zeichnen
            if abill.smokecount == 0 and abill.speed > 0.5:
                smoke = Smoke(abill.rect, 50, self.gfx)
                self.smokesprites.add(smoke)
            #Kollision zweier FremdBills:
            for bbill in self.andrebills:
                if abill != bbill:
                    if bbill.rect.colliderect(abill.rect ):
                        if abill.typ == bbill.typ:
                            abill.kill = True
                            bbill.kill = True
                        if abill.typ == 2 and bbill.typ == 1:
                            bbill.kill = True
                            if abill.owner == -1:
                                self.addtoscore(abill.rect.centerx, abill.rect.top, 50)
            
            #kollidiert Bill mit einem Fremdbill, wird der Fremdbill zerstört
            if self.state == "ingame":
                if self.bill.rect.colliderect(abill.rect):
                    ##handelt es sich um einen grünen oder roten bill, verliert der Spieler ein leben
                    if abill.typ == 2:
                        # Aber nur, wenn self bill nicht unverwundbar
                        if self.bill.invincible <= 0:
                            #und wenn self.bill nicht unsichtbar!
                            if self.bill.visible == True:
                                self.bill.kill = True
                                #if self.replay == 1:
                                #   g = GEvent()
                                #   g.set_skill(self.time)
                                #   self.evpipe.add(g)  
                    else:
                        self.addtoscore(abill.rect.centerx, abill.rect.top, 30)
                    abill.kill = True
            #kollidiert der bill mit einem KollHard Objekt, wird der Bill zerstört.
            for krect in self.KollHard :
                if krect.rect.colliderect( abill.rect ): 
                    if abill.bounce == False:
                        abill.kill = True
                    else:
                        abill.det_turn(krect.rect)
            #alle bills die aus dem Level fliegen, löschen
            if abill.rect.left < self.levelsize.left:
                if abill.bounce == False:
                    abill.kill = True
                else:
                    abill.det_turn(self.left_wall)
            elif abill.rect.right > self.levelsize.right:
                if abill.bounce == False:
                    abill.kill = True
                else:
                    abill.det_turn(self.right_wall)
            elif abill.rect.top < self.levelsize.top:
                if abill.bounce == False:
                    abill.kill = True
                else:
                    abill.det_turn(self.top_wall)
            elif abill.rect.bottom > self.levelsize.bottom:
                if abill.bounce == False:
                    abill.kill = True
                else:
                    abill.det_turn(self.bottom_wall)
            
            # Ist der Bill zu entfernen ?
            if abill.kill == True:
                deb = 3 + random.randrange(3)
                deb2 = deb + 1 
                if deb2 > 6:
                    deb2 = 3
                deb3 = deb2 + 1
                if deb3 > 6:
                    deb3 = 3
                ## Schuttstücke erstellen
                if self.allowschutt:
                    blockstck = Blockstuck(abill.rect.left, abill.rect.top - 20, deb, self.schuttfall, self.gfx,37,40)
                    self.blockstsprites.add(blockstck)
                
                    blockstck = Blockstuck(abill.rect.right, abill.rect.top - 20, deb2, self.schuttfall, self.gfx,37,40)
                    self.blockstsprites.add(blockstck)
                
                    blockstck = Blockstuck(abill.rect.left, abill.rect.bottom - 20, deb3, self.schuttfall, self.gfx,37,40)
                    self.blockstsprites.add(blockstck)
                
                    blockstck = Blockstuck(abill.rect.right, abill.rect.bottom - 20, deb, self.schuttfall, self.gfx,37,40)
                    self.blockstsprites.add(blockstck)
                # Fremdbill löschen
                self.andrebills.remove(abill)
        
    
    def collide_Fremdbills(self):
        # Für jeden Fremdbill
        killist = []    
        for i in xrange(0,len(self.fremdbills)):
            #rauch zeichnen
            if self.fremdbills[i].smokecount == 0 and self.fremdbills[i].speed > 0.5:
                smoke = Smoke(self.fremdbills[i].rect, 50, self.gfx)
                self.smokesprites.add(smoke)
            #Kollision zweier FremdBills:
            for j in xrange(i, len(self.fremdbills)):
                if self.fremdbills[i] != self.fremdbills[j]:
                    if self.fremdbills[j].rect.colliderect(self.fremdbills[i].rect ):
                        if self.fremdbills[i].typ == self.fremdbills[j].typ:
                            self.fremdbills[i].kill = True
                            if killist.count(i) == 0:
                                killist.append(i)
                            self.fremdbills[j].kill = True
                            if killist.count(j) == 0:
                                killist.append(j)
                        if self.fremdbills[i].typ == 2 and self.fremdbills[j].typ == 1:
                            self.fremdbills[j].kill = True
                            if killist.count(j) == 0:
                                killist.append(j)
                            if self.fremdbills[i].owner == -1:
                                self.addtoscore(self.fremdbills[i].rect.centerx, self.fremdbills[i].rect.top, 50)
                        if self.fremdbills[j].typ == 2 and self.fremdbills[i].typ == 1:
                            self.fremdbills[i].kill = True
                            if self.fremdbills[j].owner == -1:
                                self.addtoscore(self.fremdbills[j].rect.centerx, self.fremdbills[j].rect.top, 50)
            
            #kollidiert Bill mit einem Fremdbill, wird der Fremdbill zerstört
            if self.state == "ingame":
                if self.bill.rect.colliderect(self.fremdbills[i].rect):
                    ##handelt es sich um einen grünen oder roten bill, verliert der Spieler ein leben
                    if self.fremdbills[i].typ == 2:
                        # Aber nur, wenn self bill nicht unverwundbar
                        if self.bill.invincible <= 0:
                            #und wenn self.bill nicht unsichtbar!
                            if self.bill.visible == True:
                                self.bill.kill = True
                                    
                    else:
                        self.addtoscore(self.fremdbills[i].rect.centerx, self.fremdbills[i].rect.top, 30)
                    self.fremdbills[i].kill = True
                    if killist.count(i) == 0:
                        killist.append(i)
            #kollidiert der bill mit einem KollHard Objekt, wird der Bill zerstört.
            for krect in self.KollHard :
                if krect.rect.colliderect( self.fremdbills[i].rect ): 
                    if self.fremdbills[i].bounce == False:
                        self.fremdbills[i].kill = True
                        if killist.count(i) == 0:
                            killist.append(i)
                    else:
                        self.fremdbills[i].det_turn(krect.rect)
            #alle bills die aus dem Level fliegen, löschen
            if self.fremdbills[i].rect.left < self.levelsize.left:
                if self.fremdbills[i].bounce == False:
                    self.fremdbills[i].kill = True
                    if killist.count(i) == 0:
                        killist.append(i)
                else:
                    self.fremdbills[i].det_turn(self.left_wall)
            elif self.fremdbills[i].rect.right > self.levelsize.right:
                if self.fremdbills[i].bounce == False:
                    self.fremdbills[i].kill = True
                    if killist.count(i) == 0:
                        killist.append(i)
                else:
                    self.fremdbills[i].det_turn(self.right_wall)
            elif self.fremdbills[i].rect.top < self.levelsize.top:
                if self.fremdbills[i].bounce == False:
                    self.fremdbills[i].kill = True
                    if killist.count(i) == 0:
                        killist.append(i)
                else:
                    self.fremdbills[i].det_turn(self.top_wall)
            elif self.fremdbills[i].rect.bottom > self.levelsize.bottom:
                if self.fremdbills[i].bounce == False:
                    self.fremdbills[i].kill = True
                else:
                    self.fremdbills[i].det_turn(self.bottom_wall)
            
        # Ist ein Bill zu entfernen ?
        for ln in killist:
            for i in xrange(0, len(self.fremdbills)):
                if self.fremdbills[i].kill == True:
                    deb = 3 + random.randrange(3)
                    deb2 = deb + 1 
                    if deb2 > 6:
                        deb2 = 3
                    deb3 = deb2 + 1
                    if deb3 > 6:
                        deb3 = 3
                    ## Schuttstücke erstellen
                    if self.allowschutt:
                        blockstck = Blockstuck(self.fremdbills[i].rect.left, self.fremdbills[i].rect.top - 20, deb, self.schuttfall, self.gfx,37,40)
                        self.blockstsprites.add(blockstck)
                
                        blockstck = Blockstuck(self.fremdbills[i].rect.right, self.fremdbills[i].rect.top - 20, deb2, self.schuttfall, self.gfx,37,40)
                        self.blockstsprites.add(blockstck)
                
                        blockstck = Blockstuck(self.fremdbills[i].rect.left, self.fremdbills[i].rect.bottom - 20, deb3, self.schuttfall, self.gfx,37,40)
                        self.blockstsprites.add(blockstck)
                
                        blockstck = Blockstuck(self.fremdbills[i].rect.right, self.fremdbills[i].rect.bottom - 20, deb, self.schuttfall, self.gfx,37,40)
                        self.blockstsprites.add(blockstck)
                
                    del self.fremdbills[i]  
                    break
    
    def use_item(self):
        if self.bill.allowmove == True:
            if self.bill.rect.top > self.levelsize.top and self.bill.rect.left > self.levelsize.left and self.bill.rect.right < self.levelsize.right and self.bill.rect.bottom < self.levelsize.bottom:
                for item in self.itemslist:
                    if item.owner == -1 and item.deployed == False:
                        #Item Nr. 4: Bill für 7 Sekunden unverwundbar + Turbo
                        if item.typ == 4:
                            item.ltime = 0
                            self.bill.invincible = 9000
                            self.bill.set_speed(30,self.lft)    
                        elif item.typ == 3:
                            nbill = Bill(self.bs, -10, -10, 2, self.bill.rotation, 2, self.gfx)              
                            ## Position und geschwindigkeit von eigenem Bill übernehmen
                            nbill.rect.top = self.bill.rect.top
                            nbill.rect.left = self.bill.rect.left
                            nbill.set_speed(self.bill.speed + 7,self.lft)
                            ## Bewegung herausrechnen
                            nbill.uncollide(self.bill.rect)
                            ## Besitz des neuen Bills übernehmen
                            nbill.owner = -1
                            #item absetzen
                            item.deployed = True 
                            self.andrebills.add(nbill)
                            #self.fremdbills.append(nbill)
                        else:
                            ## Position von eigenem Bill übernehmen
                            item.rect.centery = self.bill.rect.centery 
                            item.rect.centerx = self.bill.rect.centerx
                            ## Bewegung herausrechnen
                            item.rect.left -= self.bill.rect.width * self.bill.richtung
                            item.rect.top -= self.bill.rect.height * self.bill.steigung
                            #item absetzen
                            item.deployed = True 
                            #if self.replay == 1:
                            ## Item Nr. 1 beschleunigt den Spieler sofort
                        if item.typ == 1:
                            self.bill.set_speed(30, self.lft)
                            item.set_image()
                
                
    def remove_oldpoints(self):
        #veraltete Scores entfernen
        for score in self.scores:
            if score.lifetime <= 0:
                self.scores.remove(score)
                
    def addtoscore(self, x, y, points):
        # Punkte zu Punktestand addieren
        if self.mode == 1:
            self.oldscore = self.score
            self.score += points
            p = Points(self.bs, x, y, self.gfx.scorefont, points)
            ##prüfen, ob punkte auf der X-Achse im Bildschirmbereich liegen
            if p.rect.left < 0:
                p.rect.left = int(self.bs.xres/50)
            elif p.rect.right > self.bs.xres:
                p.rect.right = int(self.bs.xres - (self.bs.xres/50))
            ##prüfen, ob punkte auf der y-Achse im Bildschirmbereich liegen
            if p.rect.top < 0:
                p.rect.top = int(self.bs.yres/15)
            elif p.rect.top > self.bs.yres:
                p.rect.top = int(self.bs.yres - (self.bs.yres/15))
            #Punkte zur Punkteliste hinzufügen    
            self.scores.add(p)
                
    def collide_schutt(self):
        ##count auf offset setzen
        collcount = self.stckoffset  
        for blockstck in self.blockstsprites.sprites():
            #screen.blit(self.background, blockstck.rect, blockstck.rect)
            #prüfen, ob bruchstück entfernt werden kann
            if blockstck.ltime <= 0 and not blockstck.persistent:
                self.blockstsprites.remove(blockstck)
            #kollidiert Schutt mit Boden?
            else:
                if blockstck.fall > 0:
                    if collcount == self.do_schuttcoll:
                        for krect in self.KollHard :
                            ### rect.center -> berechnung dauert
                            #if krect.rect.collidepoint( blockstck.rect.center ): 
                            if krect.rect.colliderect( blockstck.rect ): 
                                blockstck.fall = 0
                                blockstck.drift = 0
                                blockstck.dizzy = -1
                                blockstck.allowtrans = True
                                if blockstck.state == 7:
                                    blockstck.ltime = self.itemschuttzeit
                                else:
                                    blockstck.ltime = self.schuttzeit
                                
                    collcount += 1
                    if collcount > self.do_schuttcoll:
                        collcount = 1
        self.stckoffset += 1
        if self.stckoffset > self.do_schuttcoll:
            self.stckoffset = 1

    def get_background(self):
        zeit = time.strftime("%H")
        zeit = int(zeit)
        self.background = pygame.Surface((self.bs.xres, self.bs.yres))
        bg = pygame.Surface((1024,768))
        if zeit >= 9 and zeit < 19:
            bg, brect = load_image('himmel_tag.bmp')
        elif zeit >= 7 and zeit < 9:
            bg, brect = load_image('himmel_morgen.bmp')
        elif zeit >= 19 and zeit < 21:
            bg, brect = load_image('himmel_abend.bmp')
        else:
            bg, brect = load_image('himmel_nacht.bmp')
        #stillbackground, sbrect = load_image('himmel_tag.bmp')
        bg = bg.convert()
        self.background = pygame.transform.scale(bg, (self.bs.xres, self.bs.yres))
        self.background = self.background.convert()
        
    def collide_xblocks(self):
        #Kollidiert Bill des Spielers mit einem zerstörbaren Block?
        # ist es Zeit einen Zerstörten Block wieder herzustellen?   
        for xblock in self.xblocksprites.sprites():      
            if xblock.state != 0:
                ## Kollision abfragen
                ##Kollision des Blocks mit eigenem Bill überprüfen
                collide = False
                if self.state == "ingame":
                    if self.bill.rect.colliderect(xblock.rect):
                        collide = True  
                        self.bill.speed += 0.2
                        self.addtoscore(xblock.rect.centerx, xblock.rect.top, 10)
                ## Kollision allgemein mit fremdbills abfragen
                for abill in self.andrebills:
                    if abill.rect.colliderect(xblock.rect):
                        collide = True  
                        if abill.owner == -1:
                            self.addtoscore(xblock.rect.centerx, xblock.rect.top, 20)
                        abill.speed += 0.2
                    
                if collide == True:
                    deb = random.randrange(2)
                    deb2 = deb + 1 
                    if deb2 > 2:
                        deb2 = 0
                    deb3 = deb2 + 1
                    if deb3 > 2:
                        deb3 = 0
                        
                    if self.allowschutt:
                        blockstck = Blockstuck(xblock.rect.left, xblock.rect.top -20, deb, self.schuttfall, self.mapgfx, xblock.firstpiece, xblock.lastpiece)
                        if self.persistent: blockstck.persistent = True;
                        self.blockstsprites.add(blockstck)
        
                        if xblock.state < xblock.lastconstruct -1:
                            blockstck = Blockstuck(xblock.rect.right, xblock.rect.top -20, deb2, self.schuttfall, self.mapgfx, xblock.firstpiece, xblock.lastpiece)
                            if self.persistent: blockstck.persistent = True;
                            self.blockstsprites.add(blockstck)
                        
                            if xblock.state < xblock.lastconstruct -2:
                                blockstck = Blockstuck(xblock.rect.left, xblock.rect.bottom -20, deb3, self.schuttfall, self.mapgfx, xblock.firstpiece, xblock.lastpiece)
                                if self.persistent: blockstck.persistent = True;
                                self.blockstsprites.add(blockstck)
                            
                                if xblock.state < xblock.lastconstruct -3:
                                    blockstck = Blockstuck(xblock.rect.right, xblock.rect.bottom -20, deb, self.schuttfall, self.mapgfx, xblock.firstpiece, xblock.lastpiece)
                                    if self.persistent: blockstck.persistent = True;
                                    self.blockstsprites.add(blockstck)
                    if not xblock.persistent:          
                        xblock.state = 0
                        xblock.set_image()
                        xblock.startRespawn()
                        xblock.scount = 0
                    else:
                        xblock.state=0
                        xblock.set_image()
                    
    def get_scoreimage(self):
        if self.score != self.oldscore:
            self.score_image = self.gfx.font_h1.render(str(self.score), 1, (0,0,0))
            sctrect = self.score_image.get_rect()
            self.score_rect = Rect(int((self.bs.xres/1.13 )), int(self.bs.yres/76), sctrect.width, sctrect.height)
            
    def verarbeitePadEvent(self, event):
        if self.gamepad != "" and self.gamepad.configured == True:
            if self.state == "ingame":
                if event.type == JOYAXISMOTION and event.axis == self.gamepad.lenkachse:
                    if event.value >= 0.75:
                        self.bill.rot_type = 2
                    elif event.value < 0.75 and event.value > -0.75 :
                        self.bill.rot_type = 0
                    elif event.value <= -0.75:
                        self.bill.rot_type = 1
                    
                if event.type == JOYAXISMOTION and event.axis == self.gamepad.gasachse:
                    if event.value >= 0.5:
                        self.bill.sped_type = 1
                    elif event.value < 0.5 and event.value > -0.5 :
                        self.bill.sped_type = 0
                    elif event.value <= -0.5:
                        self.bill.sped_type = 2
                if event.type == JOYBUTTONDOWN  and event.button == self.gamepad.actionbutton:
                    self.useItem = True
                    
            elif self.state == "mainmenu":
                if event.type == JOYAXISMOTION and event.axis == self.gamepad.gasachse:
                    if event.value >= 0.98:
                        self.menu_up()
                    elif event.value <= -0.98:
                        self.menu_down()
                        
                if event.type == JOYBUTTONDOWN  and event.button == self.gamepad.actionbutton:
                    self.menu_select()
                
    def verarbeitePipeEvent(self):
        g = 0 
        #print "Pipe-Fetch:"
        while g != -1:
            g = self.inpipe.get(self.time)
            if(g != -1):
                #print " GEvent fetched at ", g.time ,"/", self.time
                if g.typ == 1 or g.typ == 5:
                    print "x y ", g.x, " ",g.y
                    x= g.x + self.levelsize.left
                    y= g.y + self.levelsize.top          
                    print " ", x, " ",y
                #   print ""
                if g.typ == 1:
                    #Spawn Bill
                    if g.bill_id > 0:
                        print " GEvent Creating ABill"
                        nb = Bill(self.bs, x, y, g.bill_typ, g.bill_rot, g.bill_rot, self.gfx)
                        nb.set_speed(float(g.bill_sped), self.lft)
                        nb.rotation = g.bill_rot
                        nb.get_steigung()
                        nb.set_image()
                        self.andrebills.add(nb)
                        #self.fremdbbills.append(nb)
                    else:
                        print " GEvent Updating SBill"
                        self.bill.rect.left = x
                        self.bill.rect.top = y
                        self.bill.rotation = float(g.bill_rot)
                        self.bill.set_speed(float(g.bill_sped), self.lft)
                        self.bill.get_steigung()
                        self.bill.set_image()
                elif g.typ == 3:
                    #Bill rot anpassen
                    if g.bill_id > 0:
                        nb = 0
                    else:
                        self.bill.rot_type = int(g.bill_rot)
                        print " GEvent Rotate SBill: ", self.bill.rot_type
                elif g.typ == 2:
                    #bill sped anpassen
                    if g.bill_id > 0:
                        nb = 0
                    else:
                        self.bill.sped_type = int(g.bill_sped)
                        print " GEvent Speed SBill:", self.bill.sped_type
                elif g.typ == 4:
                    #bill visible anpassen
                    if g.bill_id > 0:
                        nb = 0
                    else:
                        td = self.time - g.time
                        self.bill.shoot = g.billstate - td
                elif g.typ == 5:
                    #item ablegen
                    if g.item == 4:
                        self.bill.invincible = 9000
                        self.bill.set_speed(30, self.lft)
                    elif g.item == 2:
                        ni = Item(g.bill_id,self.gfx)
                        ni.typ = 2
                        ni.deployed = True 
                        ni.rect.left = x
                        ni.rect.top = y
                        ni.set_image()
                        ni.ltime = -1000
                        self.itemslist.append(ni)
                    elif g.item == 1:
                        ni = Item(g.bill_id, self.gfx)
                        ni.typ = 1
                        ni.rect.left = x
                        ni.rect.top = y
                        ni.deployed = True 
                        ni.ltime = 20000
                        ni.set_image()
                        self.bill.set_speed(30, self.lft)
                        self.itemslist.append(ni)
                elif g.typ == 6:
                    #Bill killen
                    self.bill.kill = True
                    print " GEvent self.bill.kill = True:"
                elif g.typ == 7:
                    #Welt gleichstellen
                    print " GEvent Welt gleichstellen: "
                    xof = self.zerox - g.x
                    yof = self.zeroy - g.y
                    #print "ZeroX: ", self.zerox ," statt ", g.x
                    #print "ZeroY: ", self.zeroy ," statt ", g.y
                    #print "Korrigiert: ", self.zerox -xof ," / ", self.zeroy - yof
                    self.moveworld(xof, yof)
                elif g.typ == 8:
                    print " GEvent GameOver! "  
                    self.state = "gameover"
        
                
            
    def get_timeimage(self):
        self.get_gtime()
        rec = str(self.timemin)
        rec += ":"
        if self.timesec < 10:
            rec += "0"+ str(self.timesec)
        else:
            rec += str(self.timesec)
        self.time_image = self.gfx.font_h1.render(rec, 1, (0,0,0))
        sctrect = self.time_image.get_rect()
        self.time_rect = Rect(int(self.bs.xres/50), int(self.bs.yres*0.9), sctrect.width, sctrect.height)
            
    def get_gtime(self):
        help = self.time
        #Minuten berechnen
        self.timemin = help / 60000
        #verbleibende Millisekunden berechnen
        help -= self.timemin * 60000
        #sekunden berechnen
        self.timesec = help / 1000
        #verbleibende Millisekunden berechnen
        help -= self.timesec * 1000
        #hundertstel berechnen
        self.timemsc = help
        
        
            
    def get_upsimage(self):
        if self.ups != self.oldups:
            self.ups_image = self.gfx.font_h1.render("x"+str(self.ups), 1, (0,0,0))
            sctrect = self.ups_image.get_rect()
            self.ups_rect = Rect(int(self.bs.xres / 10), int(self.bs.yres/45), sctrect.width, sctrect.height)
                
def main():
    """this function is called when the program starts.
    it initializes everything it needs, then runs in
    a loop until the function returns."""
    
    bs = billscreen()
    if __debug__:
        # Wenn True, Framerate anzeigen
        fpsshow = True
        MAXFPS = 200
    else:
        fpsshow = False
        MAXFPS = 45
    #### Auflösung bzw. von Kommandozeile,
    # simple code-snippet for commandline-parsing
    cmdParser = OptionParser()
    cmdParser.add_option("-f", "--fullscreen", dest="fullscreen", action="store_true", default=True, help="Play in fullscreen mode")
    cmdParser.add_option("-w", "--windowed", dest="fullscreen", action="store_false", help="Play in windowed mode.")
    cmdParser.add_option("-r", "--resolution", dest="resolution", default="", metavar="WIDTHxHEIGHT", help="Play in resolution WIDTHxHEIGHT")
    # TODO perhaps provide a listing of available resolutions (makes only sense for fullscreen)

    (opts, args) = cmdParser.parse_args()

    # use an RegEx to obtain the resolution parts
    if(len(opts.resolution) > 0):
        mo = re.compile("^(\d+)x(\d+)$").match(opts.resolution)
        try:
            t = mo.groups()
            resolution = (int(t[0]), int(t[1]))
        except AttributeError, err:
            print "Invalid Resolution"
            #print err
            exit(3)

    fullscreen = opts.fullscreen

    pygame.display.init()

    # find out which video modes are supported
    try:
        t= resolution
    except NameError, err:
        modes = pygame.display.list_modes()
        resolution = modes[0]

    # demo usage
    for a in xrange(0, len(resolution)):
        print "Mode: " + str(resolution[a])
        
    if fullscreen:
        print( "Fullscreen mode at " + str(resolution[0]) + "x" + str(resolution[1]) )
        bs.set(resolution[0],resolution[1], False)
    else:
        bs.set(int(resolution[0]/2),int(resolution[1]/2), True)
        print( "Windowed mode at " + str(bs.xres) + "x" + str(bs.yres) )
        

    pygame.display.quit()
    ########### Danke Olaf!
    
    
    #Initialize Everything
    pygame.init()
    if(bs.window):
        screen = pygame.display.set_mode((bs.xres,bs.yres), pygame.HWSURFACE | pygame.DOUBLEBUF)
    else:
        screen = pygame.display.set_mode((bs.xres,bs.yres), pygame.FULLSCREEN | pygame.HWSURFACE | pygame.DOUBLEBUF)
    area = screen.get_rect()
    pygame.display.set_caption('Bullet Bill Battle')
    pygame.mouse.set_visible(0)
    
    #init bullet bill battle game
    game = Game(bs)

    #Mixer (Sound)
    #sndmix = pygame.mixer.init(22050, -16, True, 2048)
    
    #Display The Background
    screen.blit(game.background, (0, 0))
    pygame.display.flip()
    
    pygame.joystick.init()
    joy_num = pygame.joystick.get_count()
    for a in xrange(0, joy_num):
        gp = Gamepad(a)
        gp.load()
        if game.gamepad.id == -1:
            game.gamepad = gp
            print "Gamepad gefunden und konfiguriert: "+ str(gp.stick.get_id())+ " "+ gp.stick.get_name()
        else:
            print "Gamepad gefunden:" + gp.stick.get_name()
        
    clock = pygame.time.Clock()
    
    #Prepare Game Objects
    allsprites = pygame.sprite.RenderPlain(game.bill)
    
    limit = 75
    
    #Load online Service Settings
    #game.service.loaduser()
    #if game.testservice():
    #   #if user loaded turn on recording of ghosts
    #   game.replay = 1
    #
    game.ngevent = -1
    fps_ypos = int(game.bs.yres * 0.9)
    fps_xpos = int(game.bs.xres * 0.9)
    
    #Main Loop
    while 1:
        clock.tick(limit)
        #Zeichne Hintergrund
        screen.blit(game.background, (0, 0))
        
        #Rauch erstellen?
        game.create_smokeEigen()
                
        # für jeden nicht eigenen Bill
        game.collide_Andrebills()
                            
        #Handle Input Events
        ## Ingame
        if game.state == "ingame":
            #sicherstellen, dass Spielers bill die Welt verschiebt
            #game.bill.typ = 0
            game.useItem = False
            if game.replay != 2:
                orot = game.bill.rot_type
                osped = game.bill.sped_type
                for event in pygame.event.get():
                    #Joystick Nummer [0] verarbeiten
                    game.verarbeitePadEvent(event)
                    #if event.type == JOYAXISMOTION and event.axis == joy_linksachse:
                    #   if event.value >= 0.75:
                    #      game.bill.rot_type = 2
                    #   elif event.value < 0.75 and event.value > -0.75 :
                    #      game.bill.rot_type = 0
                    #   elif event.value <= -0.75:
                    #      game.bill.rot_type = 1
                    #   
                    #if event.type == JOYAXISMOTION and event.axis == joy_schnellerachse:
                    #   if event.value >= 0.5:
                    #      game.bill.sped_type = 1
                    #   elif event.value < 0.5 and event.value > -0.5 :
                    #      game.bill.sped_type = 0
                    #   elif event.value <= -0.5:
                    #      game.bill.sped_type = 2
                    #if event.type == JOYBUTTONDOWN  and event.button == joy_aktion:
                    #   useitem = True
                    #### Ersetzt durch verarbeitePadEvent(event)
                    
                    if event.type == QUIT:
                        return
                    elif event.type == KEYDOWN and event.key == K_ESCAPE:
                        #game.bill.speed = 0
                        game.state = "prep_mainmenu"
                    elif event.type == KEYDOWN and event.key == K_LEFT:
                        game.bill.rot_type = 1
                    elif event.type == KEYDOWN and event.key == K_RIGHT:
                        game.bill.rot_type = 2
                    elif event.type == KEYUP and event.key == K_LEFT:
                        game.bill.rot_type = 0
                    elif event.type == KEYUP and event.key == K_RIGHT:
                        game.bill.rot_type = 0
                    elif event.type == KEYDOWN and event.key == K_UP:
                        game.bill.sped_type = 1
                    elif event.type == KEYUP and event.key == K_UP:
                        game.bill.sped_type = 0
                    elif event.type == KEYDOWN and event.key == K_DOWN:
                        game.bill.sped_type = 2
                    elif event.type == KEYUP and event.key == K_DOWN:
                        game.bill.sped_type = 0 
                    #elif event.type == KEYDOWN and event.key == K_i :
                    #   game.bill.invincible = 10000
                    elif event.type == KEYDOWN and event.key == K_r :
                        print "Rotation: ", game.bill.rotation    
                    elif event.type == KEYDOWN and event.key == K_SPACE :
                        ##prüfen, ob eigenes, unbenutztes Item in Liste:
                        game.useItem = True
                        
            if game.useItem == True:
                game.use_item()
                                    
        if game.state == "mainmenu":        
            #Rausfinden der besten verschiebung in Splash
            #game.moveworld(0,0)
            #print "xof:",game.zerox /game.gfx.fx, "yof:",game.zeroy /game.gfx.fy
            for event in pygame.event.get():
                #Joystick Nummer [0] verarbeiten
                game.verarbeitePadEvent(event)
                #if event.type == JOYAXISMOTION and event.axis == joy_schnellerachse:
                #   if event.value >= 0.98:
                #      game.menu_up()
                #   elif event.value <= -0.98:
                #      game.menu_down()
                #      
                #if event.type == JOYBUTTONDOWN  and event.button == joy_aktion:
                #   game.menu_select()
                #### Ersetzt durch verarbeitePadEvent(event)
                        
                if event.type == KEYDOWN and event.key == K_ESCAPE:
                    return
                elif event.type == QUIT:
                    sys.exit()
                elif event.type == KEYDOWN:
                    if event.key == K_UP:
                        game.menu_up()
                    elif event.key == K_DOWN:
                        game.menu_down()
                    elif event.key == K_q:
                        sys.exit()
                    elif event.type == KEYDOWN and event.key == K_p :
                        game.replay = 2
                    elif event.type == KEYDOWN and event.key == K_r :
                        game.replay = 1
                        game.service.loaduser()
                    elif event.type == KEYDOWN and event.key == K_o :
                        game.replay = 0
                    elif event.key == K_RETURN:
                        game.menu_select()
                        
        if game.state == "fadeout_y":
            dy = area.height / game.max + 1
            if game.t < game.max:
                surf = pygame.Surface((area.width, dy))
                surf.fill(game.fadecolor)
                screen.blit(surf, (0, dy * game.t ))
                game.t += 1
            else:
                game.state = "fadein_y"
                game.t = 0
    
        elif game.state == "fadein_y":
            dy = area.height / game.max + 1
            if game.t < game.max:
                rect = pygame.Rect((0, 0, area.width, dy))
                rect = rect.move((0, game.t*dy))
                screen.blit(stillbackground, rect, rect)
                game.t += 1
                #explosionsprites.update()
                #explosionsprites.draw(screen)
            else:
                screen.blit(game.background, (0,0))
                game.state = game.nextstate
                game.nextstate = ""
                game.t = 0

        if game.state == "gameover":
            game.get_gtime()
            game.loadscreen("Verarbeite Highscores ")
            game.highscores = HighScores()
            game.highscores.set(game.map, game.mode)
            game.highscores.load()
            if game.mode == 2:
                game.score = game.time  
            
            hs = HighScoreEntry(game.player_name, game.score, game.mode)
            i = game.highscores.add(hs)
            game.loadscreen("Speichere Highscores ")
                
            print "Highscore eingefügt, Rang ", i
            
            #Nur wenn Highscore eingefügt wurde, Geist speichern
            if i != 0:
            #   ghost = game.evpipe.save(game.bs, game.get_maphash())
                game.highscores = HighScores()
                game.highscores.set(game.map, game.mode)
                game.highscores.load()
            #   hs.replay = ghost
                game.highscores.add(hs)

                game.highscores.save()
            #print game.player_name + " died with a score of " + str(game.score)        
            game.state = "prep_highscores";
            game.get_background()
            
        if game.state == "prep_splash":
            game.load("splash.le")
            game.moveworld(670*game.gfx.fx,500*game.gfx.fy)
            game.state = "mainmenu"
            game.menu.splash()
            game.score = 0
            game.bill.visible = True
            game.bill.allowmove = False
            game.timetolaunch = -1000
            game.bill.shoot = -1000
            game.drawups = 0
            
        if game.state == "prep_mainmenu":
            if game.map != "splash.le":
                game.load("splash.le")
                game.moveworld(670 * game.gfx.fx, 500*game.gfx.fy)
                game.state = "mainmenu"
            ## Hintergrund neu laden
            #game.get_background()
            game.menu.mainmenu()
            game.mode = 0
            game.bill.speed = 0
            game.bill.visible = True
            game.bill.invincible = -1000
            game.bill.rotation = 0
            game.bill.allowmove = False
            game.timetolaunch = -1000
            game.bill.shoot = -1000
            game.drawups = 0
            game.highscores = -1
            
        if game.state == "prep_highscores":
            game.itemslist = []
            if game.map != "splash.le":
                game.load("splash.le")
                game.moveworld(670*game.gfx.fx,500*game.gfx.fy)
            game.state = "mainmenu"
            if game.nextstate == 4:
                #game.get_background()
                game.menu.highscoresmenu(game.highscores, game.score);
                game.score = -1
                game.bill.visible = True
                game.bill.allowmove = False
                game.timetolaunch = -1000
                game.bill.shoot = -1000
                game.drawups = 0
                game.nextstate = ""
            
            if game.highscores == -1:
                game.nextstate = 4
                game.players=1
                game.menu.newgamesingle()
                
            else:
                ## Hintergrund neu laden
                #game.get_background()
                # Falls Online-Service aktiv, Highscores Online abfragen
                #if game.service.useservice:
                #   game.loadscreen("Frage Online Rekorde ab")
                #   game.highscores.load_online(game.get_maphash(), game.mode, game.service)
                #   game.highscores.save()
                #   game.get_background()
                game.menu.highscoresmenu(game.highscores, game.score);
                game.score = -1
                game.bill.visible = True
                game.bill.allowmove = False
                game.timetolaunch = -1000
                game.bill.shoot = -1000
                game.drawups = 0
        
        if game.state == "restartlevel":
            game.bill = Bill(game.bs, 350,200,0,0,1,game.gfx)
            game.bill.typ = 0
            for abill in game.andrebills:
                game.andrebills.remove(abill)
            for aspawn in game.spawnerlist:
                game.spawnerlist.remove(aspawn)
            for smoke in game.smokesprites.sprite():
                game.smokesprites.remove(smoke)
            for blockstck in game.blockstsprites.sprite():
                game.blockstsprites.remove(blockstck)          
            game.fcreateblocksprites.empty()            
            game.state="ingame"
            game.score = 0
            ## Bill abschuss einleiten:
            self.prepshootbill()    

        if game.state == "reset":      
            game.load()
            
            game.state = "ingame"
            game.reset()
            game.prepshootbill()    

        elif game.state == "quit":
            sys.exit(0)
            
        elif game.state == "conf_username":
            #get font from game class
            font = game.gfx.font_h1
            #Clear background
            game.get_background()
            #render Heading
            text1 = font.render("Online Service konfigurieren", 1, (10, 10, 10))
            textpos1 = text1.get_rect(centerx=game.background.get_width()/2)
            #render Subheading
            text2 = font.render("Benutzername:", 1, (10, 10, 10))
            textpos2 = text2.get_rect(centerx=game.background.get_width()/2, top = textpos1.top + 50)
            #render username
            text3 = font.render(game.service.uname, 1, (10, 10, 10))
            textpos3 = text3.get_rect(centerx=game.background.get_width()/2, top = textpos2.top + 50)
            #Draw Everything
            game.background.blit(text1, textpos1)
            game.background.blit(text2, textpos2)
            game.background.blit(text3, textpos3)
            #process events
            for event in pygame.event.get():
                if event.type == QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key==pygame.K_ESCAPE:
                        game.get_background()
                        game.state = "mainmenu"
                        print "game.state = \"mainmenu\""
                    #if return was hit, assume the user is finished entering text and return what's been entered
                    elif event.key == pygame.K_RETURN:
                        #Go to Service Menu
                        game.get_background()
                        #changing username requires reentering password, so go to enter pw
                        game.state = "conf_pw"
                        print "game.state = \"mainmenu\""
                        game.menu.oservicemenu(game.service.uname, game.service.server)
                    #if backspace is hit, move the carat back one space and destroy the last letter
                    elif event.key == pygame.K_BACKSPACE:
                        #make sure there's something in the string first, don't want to kill what's not there
                        if len(game.service.uname)>0:
                            game.service.uname=game.service.uname[0:len(game.service.uname)-1]
                    else:
                        #add the typed letter to the string
                        game.service.uname=game.service.uname+event.unicode
                        
        elif game.state == "conf_pw":
            #get font from game class
            font = game.gfx.font_h1
            #Clear background
            game.get_background()
            #render Heading
            text1 = font.render("Online Service konfigurieren", 1, (10, 10, 10))
            textpos1 = text1.get_rect(centerx=game.background.get_width()/2)
            #render Subheading
            text2 = font.render("Passwort:", 1, (10, 10, 10))
            textpos2 = text2.get_rect(centerx=game.background.get_width()/2, top = textpos1.top + 50)
            #render username
            text3 = font.render(game.service.upw, 1, (10, 10, 10))
            textpos3 = text3.get_rect(centerx=game.background.get_width()/2, top = textpos2.top + 50)
            #Draw Everything
            game.background.blit(text1, textpos1)
            game.background.blit(text2, textpos2)
            game.background.blit(text3, textpos3)
            #process events
            for event in pygame.event.get():
                if event.type == QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key==pygame.K_ESCAPE:
                        game.get_background()
                        game.state = "mainmenu"
                    #if return was hit, assume the user is finished entering text and return what's been entered
                    elif event.key == pygame.K_RETURN:
                        #Go to Service Menu
                        game.get_background()
                        game.state = "mainmenu"
                        game.service.get_usercode()
                        game.menu.oservicemenu(game.service.uname, game.service.server)
                    #if backspace is hit, move the carat back one space and destroy the last letter
                    elif event.key == pygame.K_BACKSPACE:
                        #make sure there's something in the string first, don't want to kill what's not there
                        if len(game.service.upw)>0:
                            game.service.upw=game.service.upw[0:len(game.service.upw)-1]
                    else:
                        #add the typed letter to the string
                        game.service.upw=game.service.upw+event.unicode
        #   text3 = font.render(game.service.uname, 1, (10, 10, 10))
        #   textpos3 = text3.get_rect(centerx=game.background.get_width()/2, top = textpos2.top + 50)
        #   game.background.blit(text3, textpos3)
        #   text4 = font.render("Passwort:", 1, (10, 10, 10))
        #   textpos4 = text4.get_rect(centerx=game.background.get_width()/2, top = textpos3.top + 50)
        #   game.background.blit(text4, textpos3)
        
        elif game.state == "conf_joys":
            print "Joysticks gefunden: ", joy_num
            if joy_num >= 1:        
                joy_name = game.gamepad.stick.get_name()
                print " Joystick: ", joy_name
                joy_axcount = game.gamepad.stick.get_numaxes()
                print " Anzahl Axen: ", joy_axcount
                joy_butcount = game.gamepad.stick.get_numbuttons()
                print " Anzahl Knöpfe: ", joy_axcount
                print " Konfiguriere Joystick ..."
                
                ## Links rechts achse festlegen
                if pygame.font:
                    font = game.gfx.font_h1
                    text1 = font.render(joy_name +" konfigurieren", 1, (10, 10, 10))
                    textpos1 = text1.get_rect(centerx=game.background.get_width()/2)
                    game.background.blit(text1, textpos1)
                    #screen.blit(game.background, (0, 0))
                    text2 = font.render("Welche Achse soll zum LINKS/Rechts steuern verwendet werden?", 1, (10, 10, 10))
                    textpos2 = text2.get_rect(width=game.background.get_width()/2)
                    textpos2.top = 30
                    textpos2.left= 10
                    game.background.blit(text2, textpos2)
                    screen.blit(game.background, (0, 0))
                    pygame.display.flip()
                    game.get_background()
                else:
                    print " Welche Achse soll zum nach LINKS / Rechts steuern verwendet werden? "
                push = -100
                while push == -100:
                    clock.tick(60)
                    for event in pygame.event.get():
                        if event.type == QUIT:
                            return
                        elif event.type == KEYDOWN and event.key == K_ESCAPE:
                            return
                        elif event.type == JOYAXISMOTION:
                            if event.value > 0.75 and event.value <=1.0:
                                push = event.axis
                            if event.value > -1.0 and event.value < -0.75:
                                push = event.axis
                print "Links/rechts: Achse ", push
                joy_linksachse = push
                
                ## Beschleunigungsachse fgestlegen
                if pygame.font:
                    font = game.gfx.font_h1
                    text1 = font.render(joy_name +" konfigurieren", 1, (10, 10, 10))
                    textpos1 = text1.get_rect(centerx=game.background.get_width()/2)
                    game.background.blit(text1, textpos1)
                    screen.blit(game.background, (0, 0))
                    text3 = font.render(" Welche Axe soll zum BESCHLEUNIGEN/Abbremsen verwendet werden?", 1, (10, 10, 10))
                    textpos3 = text3.get_rect(width=game.background.get_width()/2)
                    textpos3.top = 30
                    textpos3.left= 10
                    game.background.blit(text3, textpos3)
                    screen.blit(game.background, (0, 0))
                    pygame.display.flip()
                    game.get_background()
                else:
                    print " Welche Axe soll zum BESCHLEUNIGEN/Abbremsen verwendet werden? "
                push = -100
                while push == -100 or push == joy_linksachse:
                    clock.tick(60)
                    for event in pygame.event.get():
                        if event.type == QUIT:
                            return
                        elif event.type == KEYDOWN and event.key == K_ESCAPE:
                            return
                        elif event.type == JOYAXISMOTION:
                            if event.value > 0.75 and event.value <=1.0:
                                push = event.axis
                            if event.value > -1.0 and event.value < -0.75:
                                push = event.axis
                print "Beschleunigung: Axe ", push
                joy_schnellerachse = push
                
                ## Aktionsknopf festelgen
                if pygame.font:
                    font = game.gfx.font_h1
                    text1 = font.render(joy_name +" konfigurieren", 1, (10, 10, 10))
                    textpos1 = text1.get_rect(centerx=game.background.get_width()/2)
                    game.background.blit(text1, textpos1)
                    screen.blit(game.background, (0, 0))
                    text3 = font.render("Welcher Knopf soll als Aktionsknopf verwendet werden?", 1, (10, 10, 10))
                    textpos3 = text3.get_rect(width=game.background.get_width()/2)
                    textpos3.top = 30
                    textpos3.left= 10
                    game.background.blit(text3, textpos3)
                    screen.blit(game.background, (0, 0))
                    pygame.display.flip()
                    game.get_background()
                else:
                    print "Welcher Knopf soll als Aktionsknopf verwendet werden?"
                push = -100
                while push == -100:
                    clock.tick(60)
                    for event in pygame.event.get():
                        if event.type == QUIT:
                            return
                        elif event.type == KEYDOWN and event.key == K_ESCAPE:
                            return
                        elif event.type == JOYBUTTONDOWN:
                            push = event.button
                print "Aktionsknopf:", push
                joy_aktion = push
                if game.gamepad != "":
                    game.gamepad.configure(joy_aktion, joy_schnellerachse, joy_linksachse)
                    game.gamepad.save()
            game.state = "mainmenu";
                
        
        for smoke in game.smokesprites.sprites():
                screen.blit(game.background, smoke.rect, smoke.rect)
                #prüfen, ob rauch entfernt werden kann
                if smoke.state >= 6: #so schneller als: len(smoke.images) - 1:
                    game.smokesprites.remove(smoke)
        
        #veraltete Scores entfernen
        game.remove_oldpoints()
        
        
        #Schutt Kollisionen und Zeitbedingtes Entfernen 
        game.collide_schutt()      
                            
        #prüfen, ob ein spawner Abschießt
        for bspawn in game.spawnerlist:
            if bspawn.respawn <= 0 and bspawn.respawn != -1000:
                nb = Bill(game.bs, bspawn.rect.left, bspawn.rect.top, 1, bspawn.rmin, bspawn.rmax, game.gfx)                
                if len(game.andrebills) < game.fbillmax:
                    #print "Jetzt: " + unicode(len(game.fremdbills))
                    game.andrebills.add(nb)
                    #game.fremdbills.append(nb)

        
        
        #Kollidiert Bill des Spielers mit einem zerstörbaren Block?
        # ist es Zeit einen Zerstörten Block wieder herzustellen?   
        game.collide_xblocks()
        
        ##kollidiert bill des Spielers mit boden? 
        ## Nur prüfen, wenn bill nicht kurz vor neustart steht
        if game.timetolaunch == -1000:
            for krect in game.KollHard :
                if krect.rect.colliderect( game.bill.rect ): 
                    if game.bill.invincible > 0:
                        game.bill.det_turn(krect.rect)
                    else:
                        game.bill.kill = True
                    
        if game.bill.kill == True:
            game.timetolaunch = 1000
            game.bill.speed = 0
            game.bill.allowmove = False
            game.bill.visible = False
            deb = 3 + random.randrange(3)
            deb2 = deb + 1 
            if deb2 > 6:
                deb2 = 3
            deb3 = deb2 + 1
            if deb3 > 6:
                deb3 = 3
            if game.allowschutt:
                blockstck = Blockstuck(game.bill.rect.left, game.bill.rect.top - 20, deb, 30000, game.gfx,37,40)
                game.blockstsprites.add(blockstck)
                blockstck = Blockstuck(game.bill.rect.right, game.bill.rect.top - 20, deb2, 30000, game.gfx,37,40)
                game.blockstsprites.add(blockstck)
                blockstck = Blockstuck(game.bill.rect.left, game.bill.rect.bottom - 20, deb3, 30000,game.gfx,37,40)
                game.blockstsprites.add(blockstck)
                blockstck = Blockstuck(game.bill.rect.right, game.bill.rect.bottom - 20, deb, 30000, game.gfx,37,40)
                game.blockstsprites.add(blockstck)
            game.bill.kill = False
        
        ##Fragezeichen-Block: Kollision abfragen, gegen leeren Block tauschen
        for fblock in game.fblocksprites.sprites():      
            if fblock.state == -1:
                game.fblocksprites.remove(fblock)
                game.fcreateblocksprites.add(Fcreateblock(fblock.rect.left, fblock.rect.top, game.gfx))
            elif fblock.state == -2:
                game.fblocksprites.remove(fblock)
                ## Wenn keine Blöcke mehr vorhganden, spiel beenden
                if len(game.fblocksprites) <= 0:
                    game.state = "gameover"
            else:
                ## Kollision mit eigenem Bill abfragen
                if game.state == "ingame":
                    if game.bill.rect.colliderect(fblock.rect):
                        # Im Renn-Modus kein Item zuweisen
                        if game.mode != 2:
                            noitem = True
                            for item in game.itemslist:
                                if item.owner == -1 and item.deployed == False:
                                    noitem = False
                            if noitem == True:
                                fblock.state = -1
                                game.itemslist.append(Item(-1,game.gfx))
                        # Im Rennmodus block löschen 
                        else: 
                            fblock.state = -2
                ## Kollision mit fremden Bills abfragen
                    
        ## Wenn es Zeit ist, leeren Fragezeichen Block gegen vollen Austauschen
        for fcblock in game.fcreateblocksprites.sprites():
                if fcblock.ltime <= 0:
                    game.fcreateblocksprites.remove(fcblock)
                    game.fblocksprites.add(Fblock(fcblock.rect.left, fcblock.rect.top, game.gfx))
                    
        
        #allsprites.update()
        game.bill.update(game.lft)
        
        ##steigung steht fest
        xof = Bill.xof
        yof = Bill.yof
        
        #Globalen Nullpunkt aktualisieren
        #UPDATE: Nicht nötig, entspricht map-nullpunkt
        #game.zerox -= xof
        #game.zeroy -= yof
        
        #alles was nicht relativ zum Spieler ist, muss um xof udn yof verschoben werden!
        game.movelevel(xof,yof)
        game.smokesprites.update(xof, yof)
        XBlock.lft = game.lft
        game.xblocksprites.update(xof, yof)
        #Neue: LFT in Klasse schreiben
        if game.allowschutt:
            Blockstuck.lft = game.lft
            Blockstuck.xof = xof
            Blockstuck.yof = yof
            Blockstuck.ltc = game.ltc
            game.blockstsprites.update()
            #Alt: LFT an Update übergeben
        
            #game.blockstsprites.update(xof, yof, game.lft, game.ltc)
        game.fblocksprites.update(xof, yof)
            
        game.bodensprites.update(xof, yof)
        game.vgrundsprites.update(xof, yof)
        ## Für jedes VGrundsprite prüfen, ob kollision mit Bill
        for vg in game.vgrundsprites:
            vg.collide(game.bill, game.lft)
        
        game.scores.update(xof, yof)
        ##spawner nur updaten, wenn bill.shoot == -1 ist!
        if game.bill.shoot == -1000:
            game.spawnerlist.update(xof, yof, game.lft)
            
        # wenn ingame, prüfen, ob es Zeit ist, bill zurückzusetzen
        if game.state == "ingame":
            game.checkforshoot()
        game.fcreateblocksprites.update(xof, yof, game.lft)
        
        game.andrebills.update(game.lft)
        #for abill in game.fremdbills:
        #   abill.update(game.lft)
            
        for krect in game.KollHard:
            krect.update(xof, yof)
        for it in game.itemslist:
            it.update(xof, yof, game.lft)
        
        
        #Draw Everything
        
        #Levelgrenze zeichnen
        pygame.draw.line(screen, 0, (game.levelsize.left, game.levelsize.top),(game.levelsize.right, game.levelsize.top))
        pygame.draw.line(screen, 0, (game.levelsize.left, game.levelsize.top),(game.levelsize.left, game.levelsize.bottom))
        pygame.draw.line(screen, 0, (game.levelsize.left, game.levelsize.bottom),(game.levelsize.right, game.levelsize.bottom))
        pygame.draw.line(screen, 0, (game.levelsize.right, game.levelsize.top),(game.levelsize.right, game.levelsize.bottom))
        
        #Hintergrund zeichnen
        game.bodensprites.draw(screen)
        #Rauch zeichnen
        game.smokesprites.draw(screen)
            
        #eigenen kugelwilli zeichenen
        if game.bill.visible == True:
            screen.blit(game.bill.image, game.bill.rect)
            
        game.andrebills.draw(screen)
        #for abill in game.fremdbills:
        #   screen.blit(abill.image, abill.rect)
        
        game.spawnerlist.draw(screen)
        #Zerstörbares zeichnen
        game.xblocksprites.draw(screen)
        #Fragezeichen zeichnen
        game.fblocksprites.draw(screen)
        #Leere Fragezeichen zeichnen
        game.fcreateblocksprites.draw(screen)
            
        #Vordergrund zeichnen
        game.vgrundsprites.draw(screen)
        
        #Schutt zeichnen
        if game.allowschutt:
            game.blockstsprites.draw(screen)
            
        ## score meldungen zeichnen
        game.scores.draw(screen)
            
        #Immer einen rahmen für Items zeichnen
        if game.state == "ingame" and game.replay !=2 and game.mode != 2:
            screen.blit(game.itembox, game.itemboxrect)
        #items zeichnen
        remove = -1
        for i in xrange(0, len(game.itemslist)):
            ## Für alle herumliegenden Items:
            if game.itemslist[i].deployed == True:
                ## zeichnen
                screen.blit(game.itemslist[i].image, game.itemslist[i].rect)
                ## Kollision prüfen
                ## mit eigenem Bill
                if game.bill.rect.colliderect(game.itemslist[i].rect):
                    ##Item 1 beschleunigt auf jedenfall
                    if game.itemslist[i].typ == 1:
                        game.bill.set_speed(30, game.lft)
                    if game.itemslist[i].typ == 2:
                        #Mine, der Spieler verliert ein Leben
                        if game.bill.invincible <= 0 and game.bill.visible == True:
                            game.bill.kill = True
    
                        #Mine wird zu schutt
                        if game.allowschutt:
                            game.blockstsprites.add(Blockstuck(game.itemslist[i].rect.left, game.itemslist[i].rect.top - 20, 7, 4000, game.gfx, 41,41 ))
                        #Mine wird aus Itemliste gelöscht
                        remove = i
                ## für alle fremdbills:
                for abill in game.andrebills:
                    if abill.rect.colliderect(game.itemslist[i].rect):
                        if game.itemslist[i].typ == 1:
                            abill.set_speed(30, game.lft)
                        if game.itemslist[i].typ == 2:
                            #der Bill wird gelöscht
                            abill.kill = True
                            #schutt-mine entsteht
                            if game.allowschutt:
                                game.blockstsprites.add(Blockstuck(game.itemslist[i].rect.left, game.itemslist[i].rect.top - 20, 7, 4000, game.gfx, 41,41))
                            ## Wenn die Mine dem Spieler gehörte,
                            if game.itemslist[i].owner == -1:
                                ##Punkte vergeben
                                game.addtoscore(game.itemslist[i].rect.centerx, game.itemslist[i].rect.top, 50)
                            #item-mine wird gelöscht
                            remove = i
            ## Nur eigene oder herumliegende Items zeichnen
            if game.replay !=2 and (game.itemslist[i].owner == -1 or game.itemslist[i].deployed == True):
                ##wenn eigen und nicht herumiegend, ein Rahmen zeichnen
                if game.itemslist[i].owner == -1 and game.itemslist[i].deployed == False:
                    #pygame.draw.rect(screen, 0, Rect(510,8, 54, 54))
                    screen.blit(game.itemslist[i].image, game.itemslist[i].rect)
            ## Items mit begrenzter Lebensdauer entfernen
            if game.itemslist[i].ltime <= 0 and game.itemslist[i].ltime != -1000:
                if game.itemslist[i].typ == 1:
                    if game.allowschutt:
                        game.blockstsprites.add(Blockstuck(game.itemslist[i].rect.left, game.itemslist[i].rect.top - 20, 8,4000,game.gfx, 42,42))
                remove = i
                
        if remove != -1:
            del game.itemslist[remove]
        
        if game.drawups > 0 and game.state == "ingame":
            game.get_upsimage()
            #Box für verbleibende Leben zeichnen
            screen.blit(game.livebox, game.livebox_rect)
            #verbleibende Leben zeichnen
            screen.blit(game.ups_image, game.ups_rect)
            game.drawups -= game.lft
            
        
        ## Falls im Menü, Menü zeichnen
        #blit menu
        if game.state == "mainmenu":
            menuitems = game.get_current_menu()
            selected = game.menu.selected
            d = game.gfx.fy * 300
            
            for i in xrange(0, len(menuitems)):
                cur = menuitems[i]
                if i != selected:
                    color = (0,0,0)
                else:
                    color = (200, 0, 0)
                    
                if cur.highlight == True:
                    color = (0, 100, 0)
            
                if cur.align == "center":
                    text = game.gfx.menufont_h1.render(cur.caption, 1, color)
                elif cur.align == "left":
                    text = game.gfx.menufont_h2.render(cur.caption, 1, color)
                else:
                    text = game.gfx.menufont_h3.render(cur.caption, 1, color)
                    
                trect = text.get_rect()
                trect = trect.move((0, ((game.gfx.nresy-d) / len(menuitems)) * i ))
                if i == selected:
                    game.bill.rect.top = trect.top
                    game.bill.rect.left = 300
                
                #alignment
                if menuitems[i].align == "center":
                    trect.centerx = area.centerx
                elif menuitems[i].align == "left":
                    trect.left = area.left + 80
                else:
                    trect.right = area.right - 80
                screen.blit(text, trect)
                screen.blit(game.bill.image, game.bill.rect)
            ## Im Splash-Bildschirm die aktuelle Version zeichnen
            if len(menuitems) > 7:
                if menuitems[7].caption == "Start" and menuitems[7].changestate == "mainmenu":
                    vers = game.gfx.menufont_h3.render("V "+str(game.bs.version), 1, (0,0,0))
                    vrect = vers.get_rect()
                    vrect.centerx = game.bs.xres/2
                    vrect.bottom = game.bs.yres
                    screen.blit(vers, vrect)
        
        game.lft = clock.get_time()
        
        #Wenn der Timer Läuft (erster game.bill Abschuss)
        #if game.Timer:
        if(game.timemode == True):
            game.time += game.lft
        else:
            game.time -= game.lft
            
        ##sicherstellen, dass lft immer im Zielbereich liegt
        if game.lft < 10:
            game.lft=10
        elif game.lft > 65:
            game.lft=65
        
        ##gesamtscore und verbleibende Zeit zeichnen wenn in singleplayer Punktejagd
        if game.state == "ingame" and game.mode ==1:
            game.get_scoreimage()
            game.get_timeimage()
            #Score zeichnen
            screen.blit(game.score_image, game.score_rect)
            #Zeit zeichnen
            screen.blit(game.timebox, game.timebox_rect)
            screen.blit(game.time_image, game.time_rect)
            ## Wenn keine Zeit mehr vorhanden, Spieler töten
            if game.time < 1000:
                game.ups = 1
                game.takelife()
                
        ##Verstrichene Zeit zeichnen wenn in Singleplayer Rennen
        if game.state == "ingame" and game.mode == 2:
            game.get_timeimage()
            #Zeit zeichnen
            screen.blit(game.timebox, game.timebox_rect)
            screen.blit(game.time_image, game.time_rect)
            
        ##Ergebnis Zeichnen, wenn im Battle-Mode (Rang: Treffer - Eingesteckte Treffer)
            
        fps = int(clock.get_fps())
        if game.state == "ingame":
            game.ltc = 0
            ## Wenn Framerate zu niedrig, Schuttzeit reduzieren
            if fps < 20:
                if game.schuttzeit > 100:
                    game.schuttzeit -= 100
                    game.ltc = -100
                else:
                    game.allowschutt = False
                if game.schuttfall > 10:
                    game.schuttfall -= 10
            ## Wenn Framerate hoch, Schuttzeit erhöhen
            if fps > 40:
                if game.schuttzeit < 35000:
                    game.schuttzeit += 100
                if game.schuttfall < 3000:
                    game.schuttfall += 10
        ## Wenn Framerate anzeigen
        if fpsshow:
            #text = game.gfx.menufont_h3.render(str(game.bill.speed)+","+str(game.bill.lft_speed), 1, (0,0,0))
            text =  imgstrint(fps, game.gfx.menufont_h3, (0,0,0))
            trect = text.get_rect()
            trect.top = fps_ypos
            trect.left = fps_xpos
            screen.blit(text, trect)
        
        if fps < 20:
            fps = 20
        elif fps < MAXFPS :
            limit = fps + 2
        else:
            limit = MAXFPS
        
                                
        pygame.display.flip()
#Game Over

#this calls the 'main' function when this script is executed
if __name__ == '__main__': main()

